You can use so match event listeners, but then you have to maintain it. In addition it can cause memory leaks.
Another option is to use INotifyPropertyChanged on all of your model objects, for example:
public class MyModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int id { get {...} set { OnPropertyChanged("id"); } }
public string Name { get {...} set { OnPropertyChanged("Name"); } }
public MyModel Parent { get {...} set { OnPropertyChanged("Parent"); } }
public ModelCollection Descendants { get {...} set { OnPropertyChanged("Descendants"); } }
public ModelCollection Children { get {...} set { OnPropertyChanged("Children"); } }
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Then you can use hierarchical data context and similar WPF's features which can utilize the INotifyPropertyChanged implementation without any work from your side.
Another option is to inherit DependencyObject and use DependencyProperties instead of simple properties, which WPF can utilize in similar ways. However I think DependencyObject may be an overkill in cases of non-UI elements, and INotifyPropertyChanged is preferred in such cases.
Update: I noticed you didn't mention that you need the ObservalbleCollection for UI reasons, so my comment about WPF may be redundant. Anyway I think that using INotifyPropertyChanged is anyway a good way to manage such things, and I think it is also the standard one.