meds
meds

Reputation: 22956

Trying to understand MVVM through microsoft example

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

Answers (2)

user585968
user585968

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.

Other problems

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

Pedro G. Dias
Pedro G. Dias

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

Related Questions