如何在WPF中取消Datagrid选择更改事件?

8

我知道这个问题之前已经被问过了,但是我找不到我需要的答案。

    private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

if (oOrdItem.ItemNo == 0)
                {
                    e.Handled = true;
                    MessageBox.Show("Please save the order item", "Save");
                    return;
                }
}

即使我调用 e.Handled = true;,它仍然会选择 datagrid 行。我不想调用 dataGrid1.SelectedIndex = -1; ,因为它会再次触发 selectionchanged 事件。我也尝试过 dataGrid1.UnSelectAll();。有没有其他方法来取消 selectionchanged 事件?
2个回答

6
我使用了多种方法尝试取消选择更改事件,包括从所选答案中的方法,但它们都没有起作用。然而,下面这种方法对我非常有效:
使用 datagrid 的 PreviewMouseDown 事件处理程序:
private void dataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    //get the item I am clicking on (replace MyDataClass with datatype in datagrid)
    var myItem = (e.OriginalSource as FrameworkElement).DataContext as MyDataClass;

    //check if item is different from currently selected item
    if (myItem != dataGrid.SelectedItem)
    {
         //save message dialog
         MessageBoxResult result = MessageBox.Show("Changes will be lost. Are you sure?", "Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question);

         //if click no, then cancel the event
         if (result == MessageBoxResult.No)
         {
             e.Handled = true;
         }
         else
         {
           //otherwise, reinvoke the click event
           dataGrid.Dispatcher.BeginInvoke(
              new Action(() =>
              {
                 RoutedEventArgs args = new MouseButtonEventArgs(e.MouseDevice, 0, e.ChangedButton);
                 args.RoutedEvent = UIElement.MouseDownEvent;
                 (e.OriginalSource as UIElement).RaiseEvent(args);
              }),
              System.Windows.Threading.DispatcherPriority.Input);
           }
        }
    }
}

如果用户点击“否”,则此方法能够成功保持当前行被选中,而如果用户点击“是”,则程序将如常继续执行。希望这对未来的某个人有所帮助,因为寻找一个看似简单的解决方案花费了很长时间。


-1

你有没有考虑过另一种实现方式?我在思考使用Binding和在更改SelectedItem之前进行检查的方法。下面是一个示例:

<DataGrid ItemsSource="..." SelectedItem="{Binding SelectedEntry}" />

而底层的虚拟机可能是这样的:

public class SampleVm : ViewModelBase//assuming that you are using such a base class
{
   private object _selectedEntry;
   public object SelectedEntry
   {
       get { return _selectedEntry; }
       set 
       {
           if (!SavePrevItem())
               return;

           _selectedEntry = value;
           RaisePropertyChanged("SelectedItem"); // or something similar
       }
   }

   private bool SavePrevItem()
   {
       // your logic here
   }
}

2
你确定这会起作用吗?我认为选择会改变但SelectedEntry不会。 - Demarsch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接