Collections and complex ViewModel graphs
We have already discussed how to handle change tracking in collections and in complex models and we have introduced how to handle change tracking in a MVVM based model.
We want to start where we left adding a collection to the Person class and setup the entire editing pipeline for the collection too.
class Person
{
public Person()
{
this.Addresses = new List<Address>();
}
public String FirstName { get; set; }
public String LastName { get; set; }
public IList<Address> Addresses { get; private set; }
}
class Address
{
public String Street { get; set; }
public String City { get; set; }
}If we look at the considerations we did for the simple view model is obvious that the Address class itself needs a ViewModel and an editor and also the collection exposed by the Person class needs an editor and potentially a ViewModel depending on the type of editing that we want to support.
We need to face a couple more issues related to the fact that having one graph coming from a persistent storage and one different graph bound to the UI we need to keep them in sync.
The AddressViewModel will be as simple as the PersonViewModel we already saw:
Nothing new, except for the With/Return syntax that is simply a monad like way to guard against null adding a default value.
Things get much more interesting as we look at the PersonViewModel, that revisited, now handle the Addresses list:
We are using a MementoEntityCollection<T> to keep track of changes that occurs to the collection structure, such as add or address removal, we are using the BulkLoad API to achieve 2 goals:
Add a transformation on load, we are basically iterating over
Addressinstances adding to the collectionAddressViewModelinstances, and the transformation is done in the delegate via theCreateAddressViewModelthat simply wraps theAddressinstance, if any, into theAddressViewModelinstance initializing it as we saw for thePerson/PersonViewModelrelationship;disable at once collection notifications, a
IEntityCollection<T>has built-in support for changes notification, and aMementoEntityCollection<T>for change tracking, theBulkLoadAPI will disable notifications and tracking for the entire load process re-enabling both at the end;
We then expose our Addresses list as an IEntityView, that is an IBindingListView implementation, achieving 2 goals:
In the
Viewwe can now bind the collection to aDataGrid, for example, gaining full support for sorting, filtering and column generation;We can have control, very easily, over new items generation even if the request is done by a
DataGridcontrol: simply add aEventHandlerto theAddingNewevent of theIEntityViewand create the expected instance;
The last thing to do is to manually propagate the current ChangeTrackingService instance to the collection owned by the PersonViewModel class, we do that overriding the OnMementoChanged method that is called every time the current memento tracking this instance changes.
The last thing is to update the EditorViewModel to create a sample data set; we also add a couple of commands to manage the Addresses collection and a property to keep track of the currently selected address:
Last updated