2009-03-24 6 views
32

Je souhaite activer l'utilisateur pour mettre en surbrillance une ligne sur le DataGrid WPF et appuyez sur la touche de suppression pour supprimer la ligne.Qu'est-ce que l'événement "a enfoncé la touche de suppression" pour le Datagrid WPF?

  • la fonctionnalité est déjà intégré dans l'interface utilisateur de la grille, de sorte à l'utilisateur, la ligne disparaît
  • I poignée en ce sur l'événement SelectionChanged (Code ci-dessous)
  • de boucle I par tous les « e.RemovedItems » et les supprimer avec LINQ

problème est: même lorsque vous simplement se lect une ligne et en sortir, le changement de sélection est déclenché et cette ligne est dans e.RemovedItems (ce qui est étrange, pourquoi choisir simplement quelque chose le mettre dans un conteneur RemovedItems?).

Je suis donc à la recherche d'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; 
    } 
} 

RÉPONSE:

Merci lnferis, qui était exactement ce que je cherchais, ici est mon événement de gestion des suppressions 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"); 
} 
+3

Le KeyDown devrait jamais ici, car il est déjà gestionnaire (e.Handled = true) dans le gestionnaire précédent dans la bulle. – Shimmy

Répondre

25

Les articles RemovedItems reflète les éléments supprimés de la sélection, et non de la grille.

gérer l'événement PreviewKeyDown, et utiliser la propriété SelectedItems pour supprimer les lignes sélectionnées il y a:

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 
     } 
    } 
} 
+3

Y at-il une raison DataGrid n'a pas seulement un événement RowsDeleted? WPF, par défaut, supprime graphiquement la ligne lorsque vous appuyez sur la touche Suppr. Donc, il fait déjà cette logique et boucle sur les lignes supprimées. Pourquoi ne peuvent-ils pas simplement ajouter un gestionnaire d'événements pour ne pas avoir à dupliquer ce code et vérifier les clés. – Chad

+16

Ce n'est pas très agréable, si vous modifiez une cellule et utilisez la touche Suppr pour supprimer des caractères dans la cellule, vous finirez par supprimer la ligne entière. – epalm

+2

@epalm si vous ajoutez le code 'foreach' dans' if (grid.SelectedItems.Count> 0) 'comme Edward Tanguay l'a fait, alors tout devrait fonctionner. Mais merci de l'avoir signalé! –

-1

Vous voulez gérer l'événement KeyUp ou KeyDown et vérifiez la touche enfoncée pour Supprimer.

private void OnKeyDown(object sender, KeyEventArgs e) { 
    if (Key.Delete == e.Key) { 
    // Delete pressed 
    } 
} 
+5

l'événement KeyDown ne se déclenche pas quand j'appuie sur une touche vers le bas (impair), PreviewKeyDown fonctionne bien –

17

Qu'est-ce que vous liez votre DataGrid? Idéalement, vous devez réagir aux événements CollectionChanged sur 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 construire une collection contenant Observable vos objets et le lier à ItemsSource juste à cette fin si la collection originale ne pas les événements nécessaires.

Il pourrait ne pas convenir à votre configuration spécifique, mais comment je le fais habituellement.

+0

Je suis totalement d'accord avec cette approche. Un ObservableCollection permet à votre ViewModel de gérer toutes les modifications apportées à la source de données sous-jacente. Vous n'avez pas besoin de compter sur le code-behind ... rien de grossièrement mal à le faire via code-behind ... juste plus propre en utilisant le ViewModel. –

3

S'il vous plaît 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); 
      } 
     } 
    } 
7

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; 
    } 
} 
0

Un peu plus tard à la fête, mais pour obtenir Inferis travail de réponse:

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 ... 

Ce Ret commentaire: "si vous modifiez une cellule et utilisez le supprimer la clé de supprimer certains caractères dans la cellule, vous finirez par la suppression de la ligne entière »

Questions connexes