I have a View that displays a DataGrid
which is bound to an ObservableCollection
in the ViewModel. For the sake of discussion, let's say we have a Team
View containing a Team DataGrid
, in which each row represents a Player
.
My question is about what data type I should use to represent the players in my Team
collection. Is it a good idea for the items in the collection to be ViewModels themselves? In this case, my Team
View would be associated with a single Team
ViewModel as well as any number of Player
ViewModels (in the Team collection).
Does having multiple ViewModels associated with a single View violate any design guidelines for MVVM , and is there a preferred way of implementing this scenario?
Thanks!
ViewModel is nothing but a single class that may have multiple models. It contains multiple models as a property. It should not contain any method. In the above example, we have the required View model with two properties.
Knockout now supports multiple model binding. The ko. applyBindings() method takes an optional parameter - the element and its descendants to which the binding will be activated. This restricts the activation to the element with ID someElementId and its descendants.
We will how we can communicate between 2 View Models using Messenger. Then, we will create 2 MVVM Controls by name ControlA, ControlB and try to call a method in which is there is one view model within another view model. Go to Nuget manager and install MVVM Light. Create a Folder structure like below.
No that is fine; each object should be a ViewModel in its own right. It makes for cleaner code, nicer interactions, and remember, if it works well then it's correct (even if it violates guidelines).
I would do it exactly the way you are prescribing. I'd bind my grid to a Team
, which would have an ObservableCollection<Player>
, where Player
is another ViewModel-type class. Each row item would get the Player
as its DataContext
and so you're still binding to ViewModel properties as you'd expect: and Player
can still have public
properties for ICommand
s (likely RelayCommands) for manipulation!
Hope that helps!
Far from violating guidelines, I think this is recommendated design. At least in my projects you will see this pattern repeatedly.
This pattern comes in particularly useful in conjunction with DataTemplates. For example you could define a DataTemplate in your Application.Resources for your PlayerViewModel like so:
<DataTemplate DataType="viewModels:PlayerViewModel"> <StackPanel Orientation="Vertical"> <Image Source="/Images/Player.png"/> <TextBlock Text="{Binding Name}"/> </StackPanel> </DataTemplate>
And then if you wanted to display a list of players you simply bind a ListBox etc to your TeamViewModel.Players ObservableCollection and you automatically get the above DataTemplate displayed for each player:
<ListBox ItemsSource="{Binding Players}"/>
I agree with both of the other answers (the ones by Kieren and Groky) but feel they fail to mention a very important consideration in this decision.
You should only create a view model if there is something view-specific about what you are doing. If all you are doing is binding to data and invoking commands which naturally belong on your model, there is no reason to create a view model.
For example, suppose:
In this case adding a view model between your view and your model is pointless. Such a view can bind directly to the model:
Note that instead of binding the Delete button to the Delete() method you may want to set its Command to ApplicationCommands.Delete and use a CommandBinding to invoke the Delete() method.
My point here is that in most cases if your models are well-designed there will be no need to insert a view model object. A view model is only really necessary when view-specific state needs to be tracked (such as "current Player"), conversions are too complex to be handled by simple binding, or you need commands that affect several different model objects and/or view model properties at the same time.
In my experience, if the model is correctly designed only about 50% or so of all views actually need a view model, and in the case of items in a list this is more like 20%.
An example of a time when you might use a view model for an item in a list is when you need to keep a separate "selected" flag that is part of your view but not of your model, and the basic functionality in ListBox is not enough.
By CLEAN COD SOLID principles, it is nice to associate one view model to one view. Separation of concerns should be separated for each view and it's much easier to maintain the codebase in the future. You can do it but it's not recommended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With