Binding - updating underlying class

Feb 4, 2009 at 7:17 PM

If I create a class that implements INotifyPropertyChanged and has a number of properties exposed, then I load some data and create several instances of my class populating the properties and adding each instance into a Generic.List collection. If I then set the DataGrid.ItemSource property = to my list and modify one of the values using the datagrid I can put a breakpoint on the set property on my class and see that the datagrid is updating the underlying data. GREAT.

 

However in my world everything is dynamic:- the columns are configurable as is the data being displayed. So I cannot define a class for this and instead I created a dataTable. To support the datatable I define a class that has a collection of attributes, each attribute has a name and a value. I process my data and create new instances of my class for each record, populating the collection of attributes. Each instance is then added to a collection and using the collection I build up a datatable setting each column/row value = to the attribute class. The grid displays correctly after I set the ItemSource = my new datatable. When I change a cell in the grid I can look at the datatable and see it has updated the row.

Question:- Is there anyway I can have  the underlying attribute class updated just like the example above?


Thanks Andy 

Feb 6, 2009 at 8:40 AM
Does the DataTable implement some sort of event that fires when its data is updated? If it does, you could write an event handler for that in your underlying attribute class, and make a corresponding update there. But that seems kludgly to me.

On a more basic level, are you saying that not only your data is dynamic (I can buy that one without any problems, very little real-world data is static), but also the *structure* of the data is dynamic?

Have you considered using some other approach, say, binding the DataGrid to something like an ObservableCollection<IList<>> or something along the lines of that? If you don't want to commit to putting the columns in XAML (you can always set Visiblity="Collapsed" initially and display them on an as-needed basis), you can always generate the DataGrid.Columns collection dynamically in code whenever you need to. With this particular example, the ObservableCollection<>'s CollectionChanged event could be a good place to start. IList<> or Dictionary<> seem like obvious choices for a scenario like this, and wrapping them in a collection of some sort will effectively give you an editable, bindable, multi-dimensional array.
Feb 6, 2009 at 11:52 AM
mikj, DataTable does not fire events when the data is changed. However, you can manipulate a DataTable via a DataView. The DataView wraps each DataRow in a DataRowView which implements INotifyPropertyChanged, which will give you what you want.

amitchel7, I am not entirely sure what you are trying to do ... is it something like this ....

Attribute class, contains dynamic data - name value pairs perhaps?
You populate a DataTable from a list of Attribute instances and bind this to your grid.

So, when the data in the grid is edited, the DataTable is updated, but the Attribute instances are not.

If you bind to the DataTable.DefaultView, events will be raised when items are added / removed, also, you can handle teh PropertyChanged event for each DataRowView. With these events handled you shoud be able to sycnhronise you Attribute collection.

I have examples for a few of these scenarious in the following article:

http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx

You could also remove the DataTable altogether. To do this you would need to create a suitable PropertyDescriptor for yoru Attribute class in order that the DataGrid can bind to it.

Regards,
Colin E.
--
http://www.scottlogic.co.uk/blog/wpf/ - my WPF blog
http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx - WPF DataGrid Practical Examples