2009-03-24 28 views
32

Quiero permitir que el usuario marque una fila en WPF DataGrid y presione la tecla de borrar para eliminar la fila.¿Qué es el evento "presionado la tecla borrar" para WPF Datagrid?

  • la funcionalidad ya está integrado en la interfaz de usuario de la red, por lo que el usuario, la fila desaparece
  • Actualmente me encargo de esto en el caso SelectionChanged (por debajo de código)
  • bucle I a través de todos los "e.RemovedItems" y eliminarlos con LINQ

el problema es: incluso cuando simplemente se leccione una fila y salga de ella, se activa el cambio de selección y esa fila se encuentra en e.RemovedItems (lo cual es extraño, ¿por qué simplemente al seleccionar algo lo pondría en un contenedor RemovedItems?).

Así que estoy buscando un DeleteKeyPressed evento así que simplemente puedo manejarlo. ¿Cómo se llama ese evento?

Estoy utilizando el kit de herramientas de marzo de 2009.

XAML:

<Grid DockPanel.Dock="Bottom"> 
    <toolkit:DataGrid x:Name="TheDataGrid" 
         SelectionChanged="TheDataGrid_SelectionChanged" 
         AutoGenerateColumns="True" 
         RowEditEnding="TheDataGrid_RowEditEnding"/> 

de código subyacente:

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

RESPUESTA:

Gracias lnferis, que era exactamente lo que estaba buscando, aquí es mi evento de manejo de eliminación final para la cuadrícula de datos, tenga en cuenta que el evento KeyDown no se dispara por alguna razón.

XAML:

<toolkit:DataGrid x:Name="TheDataGrid" 
        KeyDown="TheDataGrid_KeyDown" 
        PreviewKeyDown="TheDataGrid_PreviewKeyDown" 
        AutoGenerateColumns="True" 
        RowEditEnding="TheDataGrid_RowEditEnding"/> 

de código subyacente

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

KeyDown nunca debería llegar aquí porque ya es controlador (e.Handled = true) en el controlador anterior en la burbuja. – Shimmy

Respuesta

25

Los artículos RemovedItems refleja los elementos retirados de la selección, y no de la red.

controlar el evento PreviewKeyDown, y usar la propiedad SelectedItems eliminar las filas seleccionadas ahí:

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

¿Hay alguna razón por la que DataGrid no solo tenga un evento RowsDeleted? WPF, de forma predeterminada, elimina gráficamente la fila cuando presiona la tecla Eliminar. Por lo tanto, ya está haciendo esta lógica y haciendo un bucle sobre las filas eliminadas. ¿Por qué no pueden simplemente agregar un controlador de eventos para no tener que duplicar este código y verificar claves? – Chad

+16

Esto no es muy agradable, si está editando una celda y usa la tecla eliminar para eliminar algunos caracteres en la celda, terminará borrando toda la fila. – epalm

+2

@epalm si agrega el código 'foreach' dentro de' if (grid.SelectedItems.Count> 0) 'como lo hizo Edward Tanguay, entonces todo debería funcionar. ¡Pero gracias por señalarlo! –

-1

Quiere controlar el evento KeyUp o KeyDown y comprobar la tecla pulsada para Eliminar.

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

el evento KeyDown no se dispara cuando presiono una tecla hacia abajo (impar), PreviewKeyDown funciona aunque –

17

¿Qué estás encuadernación del DataGrid? Idealmente, debería reaccionar a los eventos CollectionChanged en la colección a la que se está vinculando. De esta forma, su lógica (eliminación de elementos eliminados) se separará de su UI.

Puede construir una colección Observable que contenga sus objetos y vincularla a ItemsSource solo para ese propósito si la colección original no tiene los eventos necesarios.

Puede que no se adapte a su configuración específica, pero así es como generalmente lo hago.

+0

Estoy totalmente de acuerdo con este enfoque. Un ObservableCollection le permite a su ViewModel manejar cualquier cambio al origen de datos subyacente. No tiene que depender del código subyacente ... nada gravemente incorrecto al realizarlo por código subyacente ... simplemente más limpio usando ViewModel. –

3

Por favor, siga el siguiente código. He tenido éxito con el siguiente código.

Por favor, avísame si se requieren cambios.

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" /> 

Código detrás

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 poco tarde a la fiesta, pero para obtener Inferis respuesta de trabajo:

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

epalms corrige este comentario: "si está editando una celda y usa el eliminar la clave para eliminar algunos caracteres en la celda, terminará borrando toda la fila "

Cuestiones relacionadas