Reputation: 22956
Looking at this example: https://msdn.microsoft.com/en-us/library/windows/apps/gg521153%28v=vs.105%29.aspx?f=255&MSPPError=-2147217396
It looks like the ViewModel contains a collection of Models which is set to the datacontext of the view.
In MVVM shouldn't the ViewModel be the datacontext of the view where the Model will modify the ViewModel which will then effect the View?
Upvotes: 1
Views: 66
Reputation:
TL; DR - the example is not MVVM at all.
Yes it's a poor example of MVVM. The view is bound at runtime to the LINQ result of querying a property in the "viewmodel" rather than binding to the viewmodel itself. The Accomplishments
is not used anywhere else.
In other words, in the example pointed to by the OP, the view is not bound to a viewmodel at all but rather incorrectly and directly to a collection of models. I don't believe a ObservableCollection<>
constitutes a reasonable ViewModel. (or IEnumerable<>
; IList<>
or similar)
This is the offending line in the view's code-behind:
LevelViewOnPage.DataContext = from Accomplishment in vm.Accomplishments
where Accomplishment.Type == "Level"
select Accomplishment;
Normally you would bind the view's DataContext
to the viewmodel.
Code review-wise, its actually pretty dreadful with some odd design and naming conventions.
The view makes a call to the view model via:
vm.GetAccomplishments();
...which doesn't "get" anything since it is a void
. The method fills the Accomplishments
property which you have to read anyway so too bad if you get the order wrong.
Upvotes: 5
Reputation: 3222
If you follow the SOLID principles of object oriented programming, that would be giving the ViewModel more than one reason to change. The Model is simply that - a model, a dumb object with zero intelligence.
The ViewModel's responsability is simply to keep the state of the visualisation, showing the current values for a Person for example, and to relay any changes to the proper underlying service class.
In any event, the ViewModel is where the action happens.
The neverending example of Order/OrderLines where you construct a ViewModel that contains all the properties that you'd like to display further shows that a ViewModel is all about orchestrating the objects to be displayed in a view and facilitates communication with the rest of your code
The ViewModel often also extends properties of the view such that you can for example have a property in a LoginViewModel that looks like so:
public class LoginViewModel : INotifyPropertyChanged
{
public string Username{get;set;}
public string Password{get;set;}
public bool CanLogin {
get{
return Username.Length > 0 && Password.Length > 0;
}
}
}
In the above class, you can now databind the "CanLogin" property to your "Enabled" property in the view so that the button can only be pressed when the username and password have values, even though "CanLogin" is not part of the model.
The big debate is, however, wether the ViewModel already has too many responsabilities or not, since it is both providing access to all properties of a model (responsability 1) as well as facilitating some code logic (i.e. calling "UpdatePerson" from some PersonService class) which is a violation of the Single Responsability principle.
For that reason, and to keep a cleaner separation of concerns, I often create two distinct levels of ViewModels - level 1 is the pure mapping to the model, which basically just gives my model an INotifyPropertyChanged on all of the models public properties, and in the second level, I create ViewModels that do some interaction with underlying service classes (such as "VerifyPassword()", "UpdatePerson()" etc.
Upvotes: 3