WPF Datagrid 的“按下删除键”事件是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/677326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:12:04  来源:igfitidea点击:

What is the "pressed the delete key" event for the WPF Datagrid?

wpfdatagrid

提问by Edward Tanguay

I want to enable the user to highlight a row on the WPF DataGrid and press delete keyto delete the row.

我想让用户在 WPF DataGrid 上突出显示一行,然后按删除键删除该行。

  • the functionality is already built into the UIof the grid, so to the user, the row disappears
  • I currently handle this on the SelectionChanged event(code below)
  • I loop through all the "e.RemovedItems" and delete them with LINQ
  • 该功能已经内置到网格的 UI中,因此对于用户而言,该行消失了
  • 我目前在SelectionChanged 事件(下面的代码)上处理这个
  • 我遍历所有“e.RemovedItems”并使用 LINQ 删除它们

Problem is:even when you simply selecta row and move off of it, selection change is fired and that row is in e.RemovedItems (which is odd, why would simply selecting something put it in a RemovedItems container?).

问题是:即使您只是简单地选择一行并移开它,也会触发选择更改并且该行位于 e.RemovedItems 中(这很奇怪,为什么简单地选择某些内容将其放入 RemovedItems 容器中?)。

So I am looking for a DeleteKeyPressedevent so I can simply handle it. What is that event called?

所以我正在寻找一个DeleteKeyPressed事件,以便我可以简单地处理它。那个事件叫什么?

I am using the March 2009 toolkit.

我正在使用 2009 年 3 月的工具包。

XAML:

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


ANSWER:

回答:

Thanks lnferis, that was exactly what I was looking for, here is my finished delete handling event for the datagrid, note the KeyDown event doesn't fire for some reason.

谢谢 lnferis,这正是我要找的,这是我完成的数据网格删除处理事件,注意 KeyDown 事件由于某种原因没有触发。

XAML:

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

采纳答案by Inferis

The RemovedItemsitems reflects the items removed from the selection, and not from the grid.

RemovedItems项目体现了从网格中选择删除的项目,而不是。

Handle the PreviewKeyDownevent, and use the SelectedItemsproperty to delete the selected rows there:

处理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
        }
    }
}

回答by Denis Troller

What are you binding your DataGrid to? Ideally, you should react to CollectionChanged events on the collection you are binding to. That way, your logic (deletion of removed items) will be separated from your UI.

您将 DataGrid 绑定到什么?理想情况下,您应该对要绑定到的集合上的 CollectionChanged 事件做出反应。这样,您的逻辑(删除已删除项目)将与您的 UI 分开。

You can build an Observable collection containing your objects and bind it to ItemsSource just for that purpose if the original collection does not have the necessary events.

如果原始集合没有必要的事件,您可以构建一个包含对象的 Observable 集合并将其绑定到 ItemsSource 仅用于此目的。

It might not suit your specific setup, but that's how I usually do it.

它可能不适合您的特定设置,但这就是我通常的做法。

回答by flux

XAML

XAML

<DataGrid ItemsSource="{Binding}" CommandManager.PreviewCanExecute="Grid_PreviewCanExecute" />

Code behind

背后的代码

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

回答by Kiran Ch

Please follow the below code. I have succeeded with the below code.

请按照下面的代码。我已成功使用以下代码。

Please let me know if changes are required.

如果需要更改,请告诉我。

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

回答by andy

A little late to the party, but to get Inferis answer working:

聚会有点晚了,但要让 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 ...

This fixes epalms comment: "if you're editing a cell and use the delete key to remove some characters in the cell, you'll end up deleting the whole row"

这修复了 epalms 评论:“如果您正在编辑单元格并使用删除键删除单元格中的某些字符,您最终将删除整行”

回答by JaredPar

You want to handle the KeyUp or KeyDown event and check the pressed Key for Delete.

您想要处理 KeyUp 或 KeyDown 事件并检查按下的 Key 以进行删除。

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