I’m having trouble understanding how to apply the MVVM pattern when Lists/Collections are involved.
Say the MainModel has a few properties and methods, as well as a list that contains other DetailModel objects. The DetailModel objects can be added, removed, or re-ordered.
The MainView will show a few controls related the the root model, and have a ListBox populated from the list. Each item will have it’s own sub-view via a DetailModelView UserControl.
Finally, there is a MainViewModel. This has properties backed by the MainModel‘s properties and methods, bound to the Main View, with change notification keeping everything in sync. (Up to this point, I am comfortable with the pattern – more stating this in case there is something fundamental I am missing…)
When it comes to handling the list, I get confused. I have come across several examples where the MainViewModel simply exposes the list of DetailModels to the view, and the DetailModelViews are bound directly to the models. This functions, but is problematic. It does not consistently following the pattern (no DetailViewModel exists), and it drives me to include some UI-related code in my detail models. It seems clear to me that the MainViewModel should expose a list of DetailViewModels for the UI to bind, but I am stuck on how to implement such a thing!
How should manage the two lists (DetailModels and DetailViewModels)? I am really confused as where I initially populate the DetailViewModel list, and how I should handle adding, removing, or changing the order of the items to keep them synchronized!
Usually
Modelsare nothing more than data objects. They shouldn’t contain any code to do things like add/remove items from a list. This is theViewModel'sjob.In your case, I would create a
MainViewModelthat has the following properties:ObservableCollection<DetailViewModel> DetailsICommand AddDetailCommandICommand RemoveDetailCommandIf your
MainModelclass is a data object, you can either expose it, or it’s properties from theMainViewModelas well. Exposing it’s Properties is the “MVVM purist” approach, while exposing the entire Model is sometimes more practical.Your
MainViewModelis in charge of creating the initial list ofDetailViewModels, and it is in charge of Adding/Removing these items as well. For example, in thePropertyChangedevent for theMainViewModel.MainModelproperty, it might rebuild theMainViewModel.Detailscollection, and theCollectionChangedevent for theMainViewModel.Detailsproperty would updateMainViewModel.MainModel.Details