Is there a standardized way to sync a collection of Model objects with a collection of matching ModelView objects in C# and WPF? I'm looking for some kind of class that would keep the following two collections synced up assuming I only have a few apples and I can keep them all in memory.
Another way to say it, I want to make sure if I add an Apple to the Apples collection I would like to have an AppleModelView added to the AppleModelViews collection. I could write my own by listening to each collections' CollectionChanged event. This seems like a common scenario that someone smarter than me has defined "the right way" to do it.
public class BasketModel
{
public ObservableCollection<Apple> Apples { get; }
}
public class BasketModelView
{
public ObservableCollection<AppleModelView> AppleModelViews { get; }
}
The article Using MVVM to provide undo/redo provides MirrorCollection class to achieve the view-model and model collections synchronization.
http://blog.notifychanged.com/2009/01/30/viewmodelling-lists/
While Sam Harwell's solution is pretty good already, it is subject to two problems:
this._source.CollectionChanged += OnSourceCollectionChanged
is never unregistered, i.e. athis._source.CollectionChanged -= OnSourceCollectionChanged
is missing.viewModelFactory
, there is no way of knowing when these event handlers may be detached again. (Or generally speaking: You cannot prepare the generated view models for "destruction".)Therefore I propose a solution that fixes both (short) shortcomings of Sam Harwell's approach:
To deal with the first of the two problems, you can simply set
Source
to null in order to get rid of theCollectionChanged
event handler.To deal with the second of the two problems, you can simply add a
viewModelRemoveHandler
that allows to to "prepare your object for destruction", e.g. by removing any event handlers attached to it.You can find an example (and explanations) here too : http://blog.lexique-du-net.com/index.php?post/2010/03/02/M-V-VM-How-to-keep-collections-of-ViewModel-and-Model-in-sync
Hope this help
OK I have a nerd crush on this answer so I had to share this abstract factory I added to it to support my ctor injection.
Which builds off of this:
And this:
And here is the null checker for completeness:
Resetting an collection to a default value or to match a target value is something i've hit quite frequently
i Wrote a small helper class of Miscilanious methods that includes
which covers most of my needs the first would probably be most applicable as your also converting types
note: this only Syncs the elements in the collection not the values inside them
I've written some helper classes for wrapping observable collections of business objects in their View Model counterparts here