sony
sony

Reputation: 1503

How to Cancel Datagrid selection changed event in WPF?

I know this question is asked before, but I couldnt find what I am looking for.

    private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

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

Even if I call e.Handled = true; it will select the datagrid row. I dont want to call dataGrid1.SelectedIndex =-1; because it will trigger selectionchanged event again. I also tried dataGrid1.UnSelectAll(); Any other way to cancel the selectionchanged event?

Upvotes: 8

Views: 6178

Answers (2)

Drew Jex
Drew Jex

Reputation: 875

I used a variety of methods to try to cancel the selection changed event, including the method from the selected answer, but none of them worked. This, however, worked great for me:

Using the PreviewMouseDown event-handler for the datagrid:

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

This successfully keeps the current row selected if the user clicks "No", and if they click "Yes", then execution will continue as normal. Hopefully this helps someone in the future, because it took a long time to find something that would work for a seemingly simple problem.

Upvotes: 6

DHN
DHN

Reputation: 4865

Did you think about an alternative implementation? I'm thinking on Binding and a check method before changing the SelectedItem. An illustration:

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

and the underlying VM could look like this:

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

Upvotes: -1

Related Questions