2009-03-24 5 views
32

ユーザーを有効にしたいWPF DataGridで行を強調表示し、削除キーを押して行を削除します。WPF Datagridの「キーを押した」イベントとは何ですか?

  • 機能が既にグリッドのUIに組み込ま、ユーザに、行が
  • 私は現在(コード以下)SelectionChangedイベント
  • Iループでこれを扱う消えるようですすべての「e.RemovedItems」を通って、問題があるLINQ

でそれらを削除します。場合でも、あなたは、単にSE行を選択して移動すると、選択変更が発生し、その行が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; 
    } 
} 

ANSWER:

おかげ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"); 
} 
+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) 'の中に追加すると、Edward Tanguayのようにすべて動作するはずです。しかし、それを指摘してくれてありがとう! –

-1

あなたはkeyUpイベントまたはKeyDownイベントイベントを処理し、削除のために押されたキーを確認したいです。

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

KeyDown(奇数)キーを押したときにKeyDownイベントが発生しないが、PreviewKeyDownは機能する –

17

をあなたがあなたのデータグリッドをバインドしていますか? バインドするコレクションのCollectionChangedイベントに反応するのが理想的です。そうすれば、あなたのロジック(削除されたアイテムの削除)はあなたのUIから分離されます。

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

あなたの設定に合わないかもしれませんが、それは私が通常やる方法です。

+0

私はこのアプローチに全く同意します。 ObservableCollectionを使用すると、ViewModelは基になるデータバインドされたソースの変更を処理できます。あなたはコードビハインドに頼る必要はありません...コードビハインドを使ってコードビハインドを行うことでひどく間違ったことはありません... ViewModelを使用しているクリーナーだけです。 –

3

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

変更が必要な場合は教えてください。少し遅れて相手に

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

XAML

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

コードが、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コメ​​ント: "セルを編集してキーを削除してセル内のいくつかの文字を削除すると、行全体が削除されてしまいます」

0

背後

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); 
      } 
     } 
    } 
関連する問題