2009-03-24 1 views
32

Я хочу, чтобы пользователь выделил строку в WPF DataGrid и нажмите клавишу удаления, чтобы удалить строку.Что такое событие «нажатие кнопки удаления» для WPF Datagrid?

  • функциональность уже встроена в UI сетки, так что пользователю, то строка исчезает
  • я в настоящее время справиться с этим на событие SelectionChanged (код ниже)
  • Я петли через все «e.RemovedItems» и удалите их с помощью LINQ

Проблема: даже когда вы просто себе вывести строку и перейти от нее, сменить выделение и эта строка находится в e.RemovedItems (что странно, почему бы просто выбрать что-то, помещенное в контейнер RemovedItems?).

Итак, я ищу УдалитьKeyPressed, поэтому я могу просто обработать его. Что называется этим событием?

Я использую инструментарий March 2009.

XAML:

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

фоновым кодом:

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

ОТВЕТ:

Благодаря lnferis, это было именно то, что я искал, здесь это мое завершенное событие обработки удаления для datagrid обратите внимание, что событие KeyDown по какой-то причине не срабатывает.

XAML:

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

кода за

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 никогда не должен добираться сюда, потому что это уже обработчик (e.Handled = true) в предыдущем обработчике в пузырьке. – Shimmy

ответ

25

В RemovedItems пунктов отражает элементы, удаленные из выбора, а не из сетки.

PreviewKeyDown Берите событие, и использовать SelectedItems свойство, чтобы удалить выбранные строки там:

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

Есть ли причина, по которой DataGrid не просто имеет событие RowsDeleted? WPF по умолчанию графически удаляет строку при нажатии клавиши удаления. Таким образом, он уже выполняет эту логику и перебирает удаленные строки. Почему они не могут просто добавить обработчик событий, чтобы мне не пришлось дублировать этот код и проверять ключи. – Chad

+16

Это не очень приятно, если вы редактируете ячейку и используете ключ удаления, чтобы удалить некоторые символы в ячейке, вы в конечном итоге удалите всю строку. – epalm

+2

@epalm, если вы добавите код 'foreach' внутри' if (grid.SelectedItems.Count> 0) ', как это сделал Эдвард Тангуэй, тогда все должно работать. Но спасибо, что указали! –

-1

Вы хотите обработать событие KeyUp или KeyDown и проверить нажатой клавишу для Delete.

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

событие KeyDown не срабатывает, когда я нажимаю клавишу вниз (нечетно), PreviewKeyDown работает, хотя –

17

Что вы сшиваться DataGrid к? В идеале вы должны реагировать на события CollectionChanged в коллекции, к которой вы привязываетесь. Таким образом, ваша логика (удаление удаленных элементов) будет отделена от вашего пользовательского интерфейса.

Вы можете создать коллекцию Observable, содержащую ваши объекты, и привязать ее к ItemsSource только для этой цели, если исходная коллекция не имеет необходимых событий.

Возможно, это не подходит для вашей конкретной установки, но я так обычно это делаю.

+0

Я полностью согласен с этим подходом. ObservableCollection позволяет ViewModel обрабатывать любые изменения в базовом источнике данных. Вам не нужно полагаться на код-код ... ничего грубого неправильно сделать с помощью кода-за ... просто чище с помощью ViewModel. –

3

Пожалуйста, используйте приведенный ниже код. Мне удалось получить код ниже.

Пожалуйста, дайте мне знать, если требуются изменения.

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

код за

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

Немного опоздал на вечеринку, но, чтобы получить Inferis ответ работы:

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 комментарий: «если вы редактируете ячейку и используете удалить ключ, чтобы удалить некоторые символы в ячейке, вы в конечном итоге удалите всю строку «

Смежные вопросы