web-dev-qa-db-ja.com

WPFデータグリッドの「押された削除キー」イベントとは何ですか?

ユーザーがWPF DataGridの行を強調表示し、削除キーを押すで行を削除できるようにしたい。

  • 機能はすでにグリッドのIに組み込まれていますなので、ユーザーには行が表示されなくなります
  • 私は現在SelectionChangedイベント(以下のコード)でこれを処理しています
  • すべての「e.RemovedItems」をループし、LINQで削除します

問題は:単にselect行を移動してそこから移動した場合でも、選択の変更が発生し、その行はe.RemovedItems(これは奇妙ですが、なぜ単に何かを選択するだけでRemovedItemsコンテナーに入れられるのでしょうか?).

だから私はDeleteKeyPressedイベントを探しているので、それを簡単に処理できます。そのイベントは何と呼ばれていますか?

2009年3月のツールキットを使用しています。

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に感謝します。これがまさに私が探していたものです。データグリッドの削除処理イベントが完了しました。なんらかの理由で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");
}
35
Edward Tanguay

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
        }
    }
}
30
Inferis

DataGridを何にバインドしていますか?理想的には、バインドしているコレクションのCollectionChangedイベントに反応する必要があります。これにより、ロジック(削除されたアイテムの削除)がUIから分離されます。

元のコレクションに必要なイベントがない場合は、オブジェクトを含むObservableコレクションを作成して、その目的のためだけにItemsSourceにバインドできます。

それはあなたの特定のセットアップに合わないかもしれませんが、それは私が通常それをする方法です。

17
Denis Troller

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

以下のコードに従ってください。以下のコードで成功しました。

変更が必要な場合はお知らせください。

 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);
            }
        }
    }
3
Kiran Ch

パーティーには少し遅れますが、インフェリスの回答を機能させるには:

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のコメントが修正されます。「セルを編集していて、Deleteキーを使用してセル内の一部の文字を削除すると、行全体が削除されます」

1
andy