Je souhaite permettre à l'utilisateur de mettre en surbrillance une ligne du WPF DataGrid et d'appuyer sur la touche Suppr pour supprimer la ligne.
Le problème est le suivant: même lorsque vous simplement sélectionnez une ligne et que vous vous en éloignez, le changement de sélection est déclenché et cette ligne est dans e.RemovedItems (ce qui est étrange. Pourquoi choisir simplement dans un conteneur RemovedItems?).
Je recherche donc un événement DeleteKeyPressed afin que je puisse simplement le gérer. Comment s'appelle cet événement?
J'utilise la boîte à outils de mars 2009.
XAML:
<Grid DockPanel.Dock="Bottom">
<toolkit:DataGrid x:Name="TheDataGrid"
SelectionChanged="TheDataGrid_SelectionChanged"
AutoGenerateColumns="True"
RowEditEnding="TheDataGrid_RowEditEnding"/>
code-behind:
private void TheDataGrid_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (e.RemovedItems.Count > 0)
{
Message.Text = "The following were removed: ";
foreach (object obj in e.RemovedItems)
{
Customer customer = obj as Customer;
Message.Text += customer.ContactName + ",";
_db.Order_Details.DeleteAllOnSubmit(
customer.Orders.SelectMany(o => o.Order_Details));
_db.Orders.DeleteAllOnSubmit(customer.Orders);
_db.Customers.DeleteOnSubmit(customer);
}
}
try
{
_db.SubmitChanges();
}
catch (Exception ex)
{
Message.Text = ex.Message;
}
}
Merci, c'est exactement ce que je cherchais, voici mon événement de traitement de suppression terminé pour la grille de données, notez que l'événement KeyDown ne se déclenche pas pour une raison quelconque.
XAML:
<toolkit:DataGrid x:Name="TheDataGrid"
KeyDown="TheDataGrid_KeyDown"
PreviewKeyDown="TheDataGrid_PreviewKeyDown"
AutoGenerateColumns="True"
RowEditEnding="TheDataGrid_RowEditEnding"/>
code-behind
private void TheDataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete)
{
var grid = (DataGrid)sender;
if (grid.SelectedItems.Count > 0)
{
string checkMessage = "The following will be removed: ";
foreach (var row in grid.SelectedItems)
{
Customer customer = row as Customer;
checkMessage += customer.ContactName + ",";
}
checkMessage = Regex.Replace(checkMessage, ",$", "");
var result = MessageBox.Show(checkMessage, "Delete", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
foreach (var row in grid.SelectedItems)
{
Customer customer = row as Customer;
_db.Order_Details.DeleteAllOnSubmit(
customer.Orders.SelectMany(o => o.Order_Details));
_db.Orders.DeleteAllOnSubmit(customer.Orders);
_db.Customers.DeleteOnSubmit(customer);
}
_db.SubmitChanges();
}
else
{
foreach (var row in grid.SelectedItems)
{
Customer customer = row as Customer;
LoadData();
_db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer); //TODO: this doesn't refresh the datagrid like the other instance in this code
}
}
}
}
}
private void TheDataGrid_KeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("never gets here for some reason");
}
Les éléments RemovedItems
reflètent les éléments supprimés de la sélection et non de la grille.
Gérez l'événement PreviewKeyDown
et utilisez la propriété SelectedItems
pour supprimer les lignes sélectionnées à cet endroit:
private void PreviewKeyDownHandler(object sender, KeyEventArgs e) {
var grid = (DataGrid)sender;
if ( Key.Delete == e.Key ) {
foreach (var row in grid.SelectedItems) {
... // perform linq stuff to delete here
}
}
}
À quoi liez-vous votre DataGrid? ?__. Idéalement, vous devez réagir aux événements CollectionChanged de la collection à laquelle vous vous liez. De cette façon, votre logique (suppression des éléments supprimés) sera séparée de votre interface utilisateur.
Vous pouvez créer une collection Observable contenant vos objets et la lier à ItemsSource uniquement à cette fin si la collection d'origine ne contient pas les événements nécessaires.
Cela pourrait ne pas convenir à votre configuration spécifique, mais c'est comme cela que je le fais habituellement.
XAML
<DataGrid ItemsSource="{Binding}" CommandManager.PreviewCanExecute="Grid_PreviewCanExecute" />
Code derrière
private void Grid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
DataGrid grid = (DataGrid)sender;
if (e.Command == DataGrid.DeleteCommand)
{
if (MessageBox.Show(String.Format("Would you like to delete {0}", (grid.SelectedItem as Person).FirstName), "Confirm Delete", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
e.Handled = true;
}
}
Veuillez suivre le code ci-dessous. J'ai réussi avec le code ci-dessous.
S'il vous plaît laissez-moi savoir si des changements sont nécessaires.
private void grdEmployee_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Device.Target.GetType().Name == "DataGridCell")
{
if (e.Key == Key.Delete)
{
MessageBoxResult res = MessageBox.Show("Are you sure want to delete?", "Confirmation!", MessageBoxButton.YesNo,MessageBoxImage.Question);
e.Handled = (res == MessageBoxResult.No);
}
}
}
Un peu tard pour la fête, mais pour que Inferis réponde,
Dim isEditing = False
AddHandler dg.BeginningEdit, Sub() isEditing = True
AddHandler dg.RowEditEnding, Sub() isEditing = False
AddHandler dg.PreviewKeyDown, Sub(obj, ev)
If e.Key = Key.Delete AndAlso Not isEditing Then ...
Cela corrige le commentaire d'epalms: "si vous modifiez une cellule et utilisez la touche Suppr pour supprimer certains caractères de la cellule, vous supprimerez la ligne entière"