Thanks, Wolfgang, for the references. Custom collections do work; however, I prefer not to use them, in order to keep my domain model as clean as possible.
I think I have worked out an Adapter that will allow a multi-level containment hierarchy of IList<T> or ISet<T> to provide change notification to WPF. It is an application of the Model-View-ViewModel pattern. For the benefit of anyone reseaching this thread at a later date, here is the general approach:
Create a 'view model' (VM) object that mirrors each domain model (DM) object you want to expose in the view. The VM object only needs the properties of the DM object that will be exposed in the view. The VM object should take its corresponding DM object as a constructor parameter, and it should hold an internal reference to the DM object. The non-collection VM properties should be wired directly to the corresponding DM object properties:
public string Name
{
get { return _dmObject.Name; }
set
{
_dmObject.Name = value;
FirePropertyChangedEvent("Name");
}
Collection properties can't be wired up the same way. That's because each object in the DM collection needs to be wrapped in a VM object before it goes into the VM ObservableCollection property. So, iterate the DM collection, wrap each object, and add the wrapped object to the VM collection property.
Changes to individual objects will be propagated from the DM objects to their counterparts (and vice versa) because of the reference each VM object holds to the DM object that it wraps. But additions to and deletions from collection properties won't be propagated.
To make that happen, the VM parent object needs to subscribe to change notification on its ObservableCollection. When an object is added or deleted by WPF, the Parent object needs to react to the CollectionChanged event to push the change out to the DM. Similarly, when the DM is changed, the changing code needs to push the change to the VM. Change notification events won't work here, since neither ISET<T> nor IList<T> provides change notificastion. I'm still working out how to handle this part.
Once I have all this worked out, I plan to post an article on the subject on CodeProject, with a cross-post to NHibernateForge. I can't make any promises about when that will get done, though.
|