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; }
}
I use lazily constructed, auto-updating collections:
Using the following
ObservableViewModelCollection<TViewModel, TModel>
:I really like 280Z28's solution. Just one remark. Is it necessary to do the loops for each NotifyCollectionChangedAction? I know that the docs for the actions state "one or more items" but since ObservableCollection itself does not support adding or removing ranges, this can never happen I would think.
Well first of all, I don't think there is a single "right way" to do this. It depends entirely on your application. There are more correct ways and less correct ways.
That much being said, I am wondering why you would need to keep these collections "in sync." What scenario are you considering that would make them go out of sync? If you look at the sample code from Josh Smith's MSDN article on M-V-VM, you will see that the majority of the time, the Models are kept in sync with the ViewModels simply because every time a Model is created, a ViewModel is also created. Like this:
I am wondering, what prevents you from creating an
AppleModelView
every time you create anApple
? That seems to me to be the easiest way of keeping these collections "in sync," unless I have misunderstood your question.I may not exactly understand your requirements however the way I have handled a similar situation is to use CollectionChanged event on the ObservableCollection and simply create/destroy the view models as required.
There can be some performance issues when you add/remove a lot of items in a ListView.
We have solved this by: Extending the ObservableCollection to have an AddRange, RemoveRange, BinaryInsert methods and adding events that notify others the collection is being changed. Together with an extended CollectionViewSource that temporary disconnects the source when the collection is changed it works nicely.
HTH,
Dennis