Notification after a row is deleted from a DataGrid

Sep 20, 2009 at 7:08 PM

I need to get notified after a row has been deleted from a DataGrid.

What I'm going to do then, is to update a different object, which in turn will modify the datagrid contents.

A method hooked up to  RowEditEnding handles when new rows are added, or existing rows are modified, but isn't called when rows are deleted.

I first tried looking for something similar  to RowEditEnding, but there wasn't any.

I then tried searching this forum, and found this thread  http://wpf.codeplex.com/Thread/View.aspx?ThreadId=51987

I added a preview executed handler as outlined in the thread, and everything was called, but nothing happened... and then it struck me that it was called before anything was changed.

I then switched from using a preview executed handler to an executed handler.  But that handler was never called.

The ItemsSource of the datagrid is an ObservableCollection, so I tried listening for a Remove action there.  But that failed with a stacktrace that was caused by

  System.InvalidOperationException: Cannot change ObservableCollection during a CollectionChanged event.

 So... is there a way for me to get notification after a row has been deleted, that I haven't seen?  Was adding an executed handler supposed to be the right way of listening for a completed delete command?

 

thanx!

Sep 22, 2009 at 8:48 AM

I'm guessing the reason the handler added with CommandManager.AddExecutedHandler wasn't called, is that something else "ate" the event...?

Is there some way to get your own handler called early, and let your handler not "eat" the event, but pass it on to another handler that may need it?

Or will that mean that it will be called before the actual delete operation again?

Sep 22, 2009 at 9:01 AM

Hm... looking at this http://www.visual-studio-forum.info/8/5/596515.html  it seems the approach is to use CommandManager.AddPreviewExecutedHandler to add a handler, and in the handler:

  • do the command
  • call the code I need to be called after the delete

I'll try that.

Sep 22, 2009 at 12:26 PM

 

Ok.  That worked.  Not pretty, because of the way I had to handle a loop that caused a stack overflow (gives me an icky feeling)

CommandManager.AddPreviewExecutedHandler(schemaDataGrid, HandlePreviewSchemaRowDeleteCommands);

and then

private void HandlePreviewSchemaRowDeleteCommands(object sender, ExecutedRoutedEventArgs e)
{
     if (e.Command == DataGrid.DeleteCommand)
     {
         try
         {
             if (excutingDeleteCommand)
             {
                 return; // Avoiding loop, and dying because of stack overflow...
             }

             excutingDeleteCommand = true;
             e.Command.Execute(sender);
             DeleteRowEventHandler();
             e.Handled = true; // Set e.Handled=true here, to avoid the delete command being run twice.
         }
         finally
         {
             excutingDeleteCommand = false;
         }
     }
}

Note that executingDeleteCommand is a bool field on the UserControl subclass containing the DataGrid, and the DeleteRowEventHandler contains the code I would have run from a method handling delete events (if the datagrid had had such).

Suggestion for improvements are welcome.

Coordinator
Sep 22, 2009 at 9:47 PM

Hi, the solution you stated in the original post is valid.  Listen to item removed in the ItemsSource collection.  In order to avoid the exception, what you can do is post your operation on the Dispatcher, instead of executing it syncronously on the collection changed event.

Hope that helps,

Saied K.