0

I have a DataTable with many rows, and the DataTable is bound to a DataGrid. After deleting one or more rows via the DataGrid, I need to run specific, quite complex checks on the remaning rows.

I subscribe to the RowDeleted event, and call the checking method from there. My problem is, when deleting multiple rows via the DataGrid, the RowDeleted event is fired for every single row, calling the checking method every time. As the checking method checks all the remaining rows and all their columns, it is a big slowdown for my application, also very redundant. It would be enough to run it once all the selected rows are deleted.

Is there a way to fire only one event after deleting any number of rows?

Adam Szabo
  • 11,302
  • 18
  • 64
  • 100
  • I have deleted my answer because if you are using WPF, perhaps you should rely on WPF-type features. In any case, I don't think that there are too many approaches more efficient than the proposed one (global variable to condition how a given event is called). – varocarbas Sep 24 '13 at 09:02

3 Answers3

2

You could do this with the help of a timer. Declare a global timer and set its properties:

System.Timers.Timer _delayTimer = new System.Timers.Timer(1000);
_delayTimer.Elapsed += new EventHandler(_delayTimer_Elapsed);

 void _delayTimer_Elapsed(object sender, EventArgs e)
 {
     _delayTimer.Stop();
     Dispatcher.Invoke(new Action(UpdateMethodName)); 
     //or - with passing arguments:
     Dispatcher.Invoke(new Action<string>(UpdateMethodName), new object[]{"argument"});
 }

Now in your RowDeleted-Event, you do this:

_delayTimer.Stop();
_delayTimer.Start();

Because the timer gets restarted in the RowDeleted-event over and over again, your update logic will only get called after the last handler is fired.

Florian Gl
  • 5,984
  • 2
  • 17
  • 30
  • I'm using WPF, not WinForms, but your idea is interesting. Can you transform it to WPF? – Adam Szabo Sep 24 '13 at 08:57
  • 1
    This is WPF, it just uses the Forms.Timer object. Editted my code, not it uses a Timers.Timer object. ;) – Florian Gl Sep 24 '13 at 09:08
  • I just tried it. The "update logic" uses the GUI. The result: `InvalidOperationException: The calling thread cannot access this object because a different thread owns it.` --> OK, this one solved it: http://stackoverflow.com/questions/10267956/answered-update-mainwindow-on-timer-elapsed-event – Adam Szabo Sep 24 '13 at 09:56
  • 1
    Use the Dispatcher.Invoke method to call your update logic from a different thread: http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke.aspx – Florian Gl Sep 24 '13 at 10:01
  • Or use a `DispatcherTimer`. – Florian Gl Sep 24 '13 at 10:12
0

I would suggest you to add Checkbox column to your datagridview and provide a delete buttonand let the users to delete single or multiple rows only by selecting relevant checkbox on each row.

And add your logic which checkes remaing rows within delete command of the button. This will make sure that your logic will run once per delete regardless numbers of rows being deleted.

Kurubaran
  • 8,696
  • 5
  • 43
  • 65
  • Sorry, but this solution with modifying the `DataGrid` with additional checkboxes and a delete button is against the requirements. Also, this is about WPF `DataGrid`, not the WinForms `DataGridView`. Thanks for the reply though. – Adam Szabo Sep 24 '13 at 08:54
0

I will suggest you to handle the Delete logic in your ViewModel like:

  1. Handle the 'Delete' keydown event and bind it to the Command on viewmodel using interactivity.
  2. Bind the SelectedItems property of DataGrid to the CommandParameter for the Delete Command.
  3. In the DeleteCommand handler, remove the items from the DataGrid's ItemsSource.
  4. After deleting the items, you can run your checks
Nitin
  • 18,344
  • 2
  • 36
  • 53
  • The `DataGrid` only has a `SelectedItem` property. Can you please give an example, how to bind that to my `DataTable`? – Adam Szabo Sep 24 '13 at 09:01
  • it does have it.. but as it a readonly property, binding to it is not straight forward, so you can send them as the command parameter..updated the answer – Nitin Sep 24 '13 at 09:11
  • Sorry, it is not clear enough without a working example code. – Adam Szabo Sep 24 '13 at 09:44