Brian Triplett
Brian Triplett

Reputation: 3532

How to expose a Model's collection in the ViewModel

I'm implementing MVVM for a class which represents recursively nested types. For example:

class NestedType
{
    // Other properties here

    public Collection<NestedType> SubElements {get; set;}
}

class NestedTypeViewModel
{
    ObservableCollection<NestedType> ModelCollection { ??? }
}

How do I expose the items in the Model's collection in an observable way? (i.e., the View will be adding, creating, and modifying the subelements) I assume I need the collection in the ViewModel to be ObservableCollection<T> but what about in the Model? I could also make that an ObservableCollection and just directly expose it...

Any suggestions?

Upvotes: 5

Views: 2229

Answers (2)

sll
sll

Reputation: 62544

You can live without separate Model entity as long as you don't need to pass different Models into ViewModel, so you can stick with ViewModel which represents an actual Model data.

I would recommend to expose it using private field under the hood along with INotifyPropertyChanged:

class NestedTypeViewModel 
{     
    private ObservableCollection<NestedType> dataItems; 

    public ObservableCollection<NestedType> DataItems
    {
       get
       { 
          return this.dataItems;
       }
       private set
       {
           this.dataItems = value;
           // here is should be OnPropertyChanged("DataItems") call
       }
    } 
} 

EDIT: answer to comments

But if you already has such entity like Model - so try to inject in ViewModel by an Interface so Model and ViewModel at least would be decoupled

Upvotes: 0

dowhilefor
dowhilefor

Reputation: 11051

You can directly return the ObservableList from your model. WPF will take the reference of the Collection and registers to the CollectionChanged Event of the model collection.

class MyViewModel
{
  public ObservableCollection<NestedType> MyItems { return Model.Items; }
} 

BUT, you will break what you are trying to achieve by using MVVM. A ViewModel should not expose a model, single or collection, otherwise your view could bind to a model which you should not do in MVVM.

Well MVVM is no religion and everyone implements certain parts differently. If this is no problem for you ... Go ahead and do it directly.

If you want a clean solution, you have multiple options to go from here. Just allowing a Manager to modify the collection of the model and create a corresponding view model or My favorit approach is to have an object that syncs model and viewmodel collection, by automatically wrap newly added models in a new view model and add this vm into the parent viewmodel list.

Upvotes: 2

Related Questions