WPF DataGrid RowEditEnding Event to Call Update

I am using WPF., A datagrid connected to a database using drag and drop of the VisualStudio IDE, and found a way to update my datagrid update and add to the database in real time using the RowEditEnding event:

private void Update_WatchList(object sender, DataGridRowEditEndingEventArgs e) { UpdateWatchList(); } private void UpdateWatchList() { dsDocControlTableAdapters.DocumentWatchListTableAdapter ta = new dsDocControlTableAdapters.DocumentWatchListTableAdapter(); try { DataRowView dr = (DataRowView)documentWatchListDataGrid.SelectedItem; dsDocControl.DocumentWatchListRow dr1 = (dsDocControl.DocumentWatchListRow)dr.Row; dr1.EndEdit(); if (dr1.RowState == DataRowState.Detached) dsDocControl.DocumentWatchList.AddDocumentWatchListRow(dr1); ta.Update(dr1); } catch (Exception ex) { MessageBox.Show("Error UpdateWatchList:\n" + ex.Message); } } 

This was the result of a lot of trial and error (during which I missed, rescheduled, and again missed the appointment for dentistry), but somehow came across the need to call EndEdit () on a line to update RowState to any modification or Separately. Is this the expected workflow for what seems like a very normal use case, or is there a better way to do this?

I began to follow the path of adding the CollectionChanged event handler for the added rows, but could not get it to work, probably because I am using the ObservableCollection incorrectly:

 private void documentWatchListDataGrid_Loaded(object sender, RoutedEventArgs e) { var dg = (DataGrid)sender; if(dg==null || dg.ItemsSource == null) return; var sourceCollection = dg.ItemsSource as ObservableCollection<DataRow>; if (sourceCollection == null) return; //sourceCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(Update_WatchList); // never gets called } 

The line adding the handler is commented out because I used the handler as RowEditEnding (in the first block of code), but regardless of the fact that it never refers to this point, because the sourceCollection was always null.

My question is what is the best way to do this seemingly simple: real-time update as each row changes or is added to the WPF datagrid control?

0
source share
1 answer

Is this the expected sequence of operations for what seems like a very normal use case, or is there a better way to do this?

No, this is not an ordinary method of working with DataGrids in WPF. This seems like normal for WinForms, but not for WPF. :)

A typical DataGrid.ItemsSouce binding method is to build a class that inherits INotifyPropertyChanged to represent each row of data and binds DataGrid.ItemsSource to the ObservableCollection<T> this class

For example, you might have something like

 public class WatchListModel : INotifyPropertyChanged { // Whatever properties here public string Id { get; set; } public string Name { get; set; } } 

This class should implement INotifyPropertyChanged , and properties should raise notification of changes, however I left it for simplicity. If you need an example, check out here .

Then you will have an ObservableCollection<WatchListModel> that you will also bind your DataGrid.ItemsSource

 public ObservableCollection<WatchListModel> WatchListCollection { get; set; } 

and

 <DataGrid ItemsSource="{Binding WatchListCollection}" ... /> 

And if you need real-time updates, you need to add an event handler handler for WatchListCollection to handle add / remove and add a modified property handler to every element processed when it is modified

 public MyViewModel() { WatchListCollection = new ObservableCollection<WatchListModel>(); // Hook up initial changed handler. Could also be done in setter WatchListCollection.CollectionChanged += WatchListCollection_CollectionChanged; } void WatchListCollection_CollectionChanged(object sender, CollectionChangedEventArgs e) { // if new itmes get added, attach change handlers to them if (e.NewItems != null) foreach(WatchListModel item in e.NewItems) item.PropertyChanged += WatchListModel_PropertyChanged; // if items got removed, detach change handlers if (e.OldItems != null) foreach(WatchListModel item in e.OldItems) item.PropertyChanged -= WatchListModel_PropertyChanged; // Process Add/Remove here } void WatchListModel_PropertyChanged(object sender, PropertyChangedEventArgs e) { // Process Update here } 

This will be the correct WPF way :)

+2
source

All Articles