3
votes

I've found this text in Prism documentation. I'm starting on MVVM and I'm at lost. Can (should) I bind model properties in the view or I must create a viewmodel with a proxy property for every property in the model?

The model classes typically provide property and collection change notification events through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. This allows them to be easily data bound in the view. Model classes that represent collections of objects typically derive from the ObservableCollection class.

EDIT: Here is some extra info to help. I'm building a personal project from the ground up (so I'm designing the models too), this is the first time that I use MVVM and I want to learn properly.

My model is very hieraquical, having classes with list of more class with more list inside, building a complex tree of information. I was trying the "standard" MVVM approach, build the model with POCO and no notifications, and using List. Then building the ViewModel with proper notifications and using ObservableCollections.

The problem is, the way it is going, I'm almost reconstructing my whole model as a ViewModel AND having to keep the data synched between the to (the ObservableCollection to the List). Then I read that on the Prism docs and wondered if I should have all that trouble or just create a root ViewModel for logic and bind all the rest to the model itself.

1

1 Answers

3
votes

It depends really, if your model already implements INotifyPropertyChanged and/or IError info you might want to bind right to the model property. However if you want to do special validation and other stuff that the model knows nothing about you add the property wrappers in your view model.

This article gives a good example of a hybrid: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Often my MV properties look like this and thats quite normal:

    public string Symbol
    {
        get { return Model.Symbol; }
        set { Model.Symbol = value; this.NotifyOfPropertyChange(() => this.Symbol); }
    }

I often do NOT implement INotifyPropertyChanged in the model and thus often I have to write the wrappers.

EDIT: In response to your additional information: It can be a bit tricky to to keep the collections and lists in sync. In your case what I would do is to create a view model for each model class, but NOT wrap all the properties just access them like this: {Bindng Customer.Name}. But of course you have to create a wrapper for the collections which contain view models. The Prism documentation is, as they say themselves, just guidance, if your scenario needs a different approach then this is fine.

Take a look at this code. I only wrap the collections and the properties I will access through the model. This gives you the best of both worlds. Then IF you need a special property that does not belong into you model you can add it to the view model (see the CustomerViewModel), or if you need special notification for a certain properties.

class CompanyViewModel{
  public CopanyViewModel(Company c){
     foreach(var customer in c.Customers)
       Customers.Add(new CustomerViewModel(customer);
  }
  public Company Company {get;set;}
  public ObservableCollection<CustomerViewModel> Customers {get;set;}
}

class CustomerViewModel{
  public CustomerViewModel(Customer c){
     Customer = c;
  }
  public Customer Customer {get;set;}

  public Brush CustomerBackground{
     get{
        if(Customer.Active)
           return Brush.Greeen;
        else
           return Brush.Red;
     }
  }
 }

(This code might not work, I just typed it in here.)

Now, if you need changed notification for all models and all properties you have to either implement it in you model or in wrap all properties in a view model.