I am developing an application which uses a hierarchical object structure and displays a few key object properties from those objects on the main GUI within a DataGridView. Those values must update when the underlying data changes. I have considered a few options:
- Bind the individual DataGridView cells to the relevant object properties. I understand that this is not possible, and DGV binding is all or nothing.
- Dynamically position Textboxes over the grid cells and bind those, but this seems messy.
- Create an intermediate list/array/collection which references only the relevant object properties, and then use that list as a data source for the DataGridView.
- Respond to the PropertyChanged events. The complication is that I have got multiple classes. The top-level object exists within the UI scope, and has a child object which in turn may have multiple child objects of its own, and so on. The UI can access properties of all objects, but not their events.
I have been looking at passing the PropertyChanged event from whichever level it occurs up the chain so that it can be handled within the UI. So within a particular class I want to respond to OnPropertyChanged within that class, and within any children, and make any events raised available to the parent class. Thus events would flow up the tree to the top.
I understand how to do the two steps individually, I think, with reference to the following:
Pass click event of child control to the parent control
However, although I presume the two can be combined, I am not quite sure how to do this. In the UI I have got this:
project.PropertyChanged += new PropertyChangedEventHandler(ProjectPropertyChanged);
private void ProjectPropertyChanged(object sender, PropertyChangedEventArgs e) {
MessageBox.Show("In main UI. Project property changed!");
}
And then one level down I have got something like this:
public class Project : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Project() {
childObject.PropertyChanged += new PropertyChangedEventHandler(ProjectPropertyChanged);
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
ProjectPropertyChanged(sender, e); // this doesn't work due to different parameters
}
private void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Event available to parent class
}
}
The idea being that each class would pass its own OnPropertyChanged() events to its PropertyChanged() method, and respond to its children's OnPropertyChanged() events, and expose all to the parent class.
If doing this, ideally I would like to retain knowledge of which property changed in order to respond accordingly.
The most immediate issue is lack of compatibility between ProjectPropertyChanged and OnPropertyChanged due to different parameters. More fundamentally, though, I am not sure whether this method is workable or optimal.
How best to do this?