ユーザーがWPF DataGridの行を強調表示し、削除キーを押すで行を削除できるようにしたい。
問題は:単に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");
}
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
}
}
}
DataGridを何にバインドしていますか?理想的には、バインドしているコレクションのCollectionChangedイベントに反応する必要があります。これにより、ロジック(削除されたアイテムの削除)がUIから分離されます。
元のコレクションに必要なイベントがない場合は、オブジェクトを含むObservableコレクションを作成して、その目的のためだけにItemsSourceにバインドできます。
それはあなたの特定のセットアップに合わないかもしれませんが、それは私が通常それをする方法です。
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;
}
}
以下のコードに従ってください。以下のコードで成功しました。
変更が必要な場合はお知らせください。
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);
}
}
}
パーティーには少し遅れますが、インフェリスの回答を機能させるには:
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キーを使用してセル内の一部の文字を削除すると、行全体が削除されます」