Does WPF create a DataGrid event when adding / removing a row?

I want to recount things every time a DataGrid gets more rows or some are deleted. I tried to use the Loaded event, but it was fired only once.

I found AddingNewItem , but it starts before it was added. I have to do my stuff afterwards.

There is also a LayoutUpdated that works, but I'm afraid that LayoutUpdated does not use it, because it starts too often for my purposes.

+7
source share
7 answers

If your DataGrid is related to something, I think of two ways to do it.

You can try to get the DataGrid.ItemsSource collection and subscribe to its CollectionChanged event. This will only work if you know what type of collection it is in the first place.

 // Be warned that the 'Loaded' event runs anytime the window loads into view, // so you will probably want to include an Unloaded event that detaches the // collection private void DataGrid_Loaded(object sender, RoutedEventArgs e) { var dg = (DataGrid)sender; if (dg == null || dg.ItemsSource == null) return; var sourceCollection = dg.ItemsSource as ObservableCollection<ViewModelBase>; if (sourceCollection == null) return; sourceCollection .CollectionChanged += new NotifyCollectionChangedEventHandler(DataGrid_CollectionChanged); } void DataGrid_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { // Execute your logic here } 

Another solution is to use an event system such as Microsoft Prism EventAggregator or MVVM Light Messenger . This means that your ViewModel will send a DataCollectionChanged event DataCollectionChanged every time the associated collection changes, and your View will subscribe to receive these messages and execute your code anytime they occur.

Using EventAggregator

 // Subscribe eventAggregator.GetEvent<CollectionChangedMessage>().Subscribe(DoWork); // Broadcast eventAggregator.GetEvent<CollectionChangedMessage>().Publish(); 

Using Messenger

 //Subscribe Messenger.Default.Register<CollectionChangedMessage>(DoWork); // Broadcast Messenger.Default.Send<CollectionChangedMessage>() 
+9
source

What about DataGrid.LoadingRow(object sender, DataGridRowEventArgs e) ?

The same for unloading.

DataGrid.UnLoadingRow(object sender, DataGridRowEventArgs e) ?

+2
source

Have you tried the MVVM approach and binding to the Observable collection?

 public ObservableCollection<Thing> Items{ get { return _items; } set{ _items = value; RaisePropertyChanged("Items"); // Do additional processing here } } 

So, can you observe the addition / removal of elements without being tied to the user interface?

+2
source

If you want to use ObservableCollection and get notified of an addition or other operation, the best way to use INotifyCollectionChanged

 var source = datagrid.ItemsSource as INotifyCollectionChanged; 

Because when you expand to ObservableCollection<MyClass>() , you have to write strict MyClass (not ObservableCollection<ParentOfMyClass> ())

0
source

If you want, you can follow the RowUnloading route as others have described here, however, note that this event also fires every time the line loses focus.

However, after playing, I found that when deleting a row, the SelectedItem property of the grid is zero, and the CurrentItem property CurrentItem not zero, and so far I have seen this combination only for the deleted row (although I can not guarantee that I did not miss the exotic situation. .. however, for basic situations of withdrawal from the series, I have not seen her yet).

Therefore, when you can use the following code to filter only by deleted lines:

 private void CategoriesGrid_UnloadingRow(object sender, DataGridRowEventArgs e) { if (((DataGrid)sender).SelectedItem != null || ((DataGrid)sender).CurrentItem == null) { return; } // The rest of your code goes here } 
0
source

Depending on what “things” you want to recount, you might consider using the attached ScrollViewer.ScrollChanged event. This can be installed in XAML as follows:

 <DataGrid ... ScrollViewer.ScrollChanged="control_ScrollChanged"> 

The ScrollChangedEventArgs object has various properties that can be useful for calculating the layout and scroll position (Extent, Offset, Viewport). Note that they are usually measured in row / column numbers when using the default virtualization settings.

-1
source

I searched for a solution for this, and I found the perfect event to handle this event called UnloadingRow

 <DataGrid .... UnloadingRow="DataGrid_UnloadingRow"> ... </DataGrid> 

In your c # code and get this

 private void ProductsDataGrid_UnloadingRow(object sender, DataGridRowEventArgs e) { MyObject obj = (MyObject)e.Row.Item; // get the deleted item to handle it // Rest of your code ... // For example : deleting the object from DB using entityframework } 
-1
source

All Articles