I am getting my knickers in a twist recently about View Models (VM).
Just like this guy I have come to the conclusion that the collections I need to expose on my VM typically contain a different type to the collections exposed on my business objects.
Hence there must be a bi-directional mapping or transformation between these two types. (Just to complicate things, on my project this data is “Live” such that as soon as you change a property it gets transmitted to other computers)
I can just about cope with that concept, using a framework like Truss, although I suspect there will be a nasty surprise somewhere within.
Not only must objects be transformed but a synchronization between these two collections is required. (Just to complicate things I can think of cases where the VM collection might be a subset or union of business object collections, not simply a 1:1 synchronization).
I can see how to do a one-way “live” sync, using a replicating ObservableCollection or something like CLINQ.
The problem then becomes: What is the best way to create/delete items?
Bi-directinal sync does not seem to be on the cards – I have found no such examples, and the only class that supports anything remotely like that is the ListCollectionView. Would bi-directional sync even be a sensible way to add back into the business object collection?
All the samples I have seen never seem to tackle anything this “complex”.
So my question is: How do you solve this? Is there some technique to update the model collections from the VM? What is the best general approach to this?
I too am struggling with the bi-directional sync of two collections for use with WPF via MVVM. I blogged MVVM: To Wrap or Not to Wrap? How much should the ViewModel wrap the Model? (Part 1) and MVVM: To Wrap or Not to Wrap? Should ViewModels wrap collections too? (Part 2) regarding the question, including some sample code that shows a two way sync. However, as noted in the posts, the implementation is not ideal. I would qualify it as a proof of concept.
I like the BLINQ, CLINQ, and Obtics frameworks that Alex_P posted about. These are a very nice way to get one side of the sync behvaior. Maybe the other side (from VM to Model) can be implemented via an alternate path? I just posted part 3 on my blog that discusses some of this.
From what I can see, bi-directional via BLINQ and CLINQ is not supported in cases where the LINQ statement projects the data to a new structure.
However, it does look like CLINQ may support Bi-Directional syncing in cases where the LINQ query returns the same datatype as the underlying collection. This is more of a filtering scenario, which doesn’t match the use case of a ViewModel wrapping the data in the Model.