tags:

views:

509

answers:

3

the best way to explain is with example so:

this is the model

    public class Person 
{
public int age;
public string name;
}

this is the view model

public class PersonVM
{

}

my question is: should the vm expose the person to the datga template or encapsulate the model properties with his own properties?

+4  A: 

The view model should declare its own properties and hide the specifics of the model from the view. This gives you the most flexibility, and helps keep view model-type issues from leaking into the model classes. Usually your view model classes encapsulate the model by delegation. For example,

class PersonModel {
    public string Name { get; set; }
}

class PersonViewModel {
    private PersonModel Person { get; set;}
    public string Name { get { return this.Person.Name; } }
    public bool IsSelected { get; set; } // example of state exposed by view model

    public PersonViewModel(PersonModel person) {
        this.Person = person;
    }
}

Remember: the model shouldn't know anything about the view model that is consuming it, and the view model shouldn't know anything about the view that is consuming it. The view should know nothing about the models lurking in the background. Thus, encapsulate the model behind properties in the view model.

Jason
+7  A: 

There is not a general agreement about that question. For example it was one of the open questions about MVVM formulated by Ward Bell here:

Is the VM allowed to offer the V an unwrapped M-object (e.g., the raw Employee) ? Or must the M-object’s properties (if it is even permitted to have properties!) be exposed exclusively through the surface of a VM wrapper?

The principal advantages in expose Model properties through a VM are:

  • you can use it as a "converter on steroids", formating the model values in a convenient way for the view

  • you can inject other funcionality related to the user interface, like data validation messages, undo redo,..

The cons are:

  • you will have to duplicate a lot of code to expose all the models properties in the viewmodel.

  • if you bind the view control to the viewmodels property, you will send the propertyChanged events from the viewmodel. But what happens if the models property change from other source different from the viewmodel setter? Then it has to notify the viewmodel so you end with 2 OnPropertyChanged, one in the model and one in the viewmodel... quite complex!

So for me the correct answer is: it depends on your requirements.

DaniCE
A: 

Having a ViewModel for any Model could be worse than that. What if you have a hierarchical structure of a Model, or even a simple collection? In that case you'll have to iterate through all models and build a ViewModel instance per-model, and also to register notify-change events or other events. IMHO, this is completely insane, and unreasonable. As DaniCE said, you’ll end up with lot of code and a big headache.

Deepforest