C# MVVM – Best Practice to Extend Model in View Model

cmvvmwpf

I'm facing an issue where I have a Model which I want to implement a GUI for. As I'm exploring MVVM and WPF I will of course use a View Model between the View and Model. I will also have a need to add coordinates to some model classes that represents objects that will be drag able in the GUI. At this time, this is the only addition to these particular model classes that I need. At least at this moment. At the same time almost all, if not all, information contained in the model objects is of interest to the view.

The most important model classes are:

  • Table
  • Columns
  • Dependencies

  • Tables know of its columns.

  • Columns know which Table they belongs to.
  • Columns know 1..* Dependencies
  • Dependencies know 1..* column it represents a dependency to.

It would of course be possible to modify how these objects know of each other, if needed.

The real question here though, is; How do I make the model classes available to the View, when at the same time adding coordinates to Tables, Columns and Dependencies?

One way might be to create something like this:

public class TableViewModel
{
    public Model.Table ModelTable { get; private set; }
    public List<ColumnViewModel> Columns { get; set; }
    public float X { get; set; }
    public float Y { get; set; }
}

Is this a preferred way to forward an "extended" Model object to the View or are there patterns specifically engineered for this task?

Would regular inheritance between the objects in Model and View Model work? I'm not sure though, I like the coupling that would cause.

Or should I create View Model classes that are tailored to fit the View and then map properties from the Model object to the View Model object? This would completely remove the coupling between View and Model, but create two objects in memory, and in this case these might be very big models. Will the garbage collector drop the model objects since there will be no more references to them after they have been mapped to the view model?

Best Answer

The real question here though, is; How do I make the model classes available to the View, when at the same time adding coordinates to Tables, Columns and Dependencies?

Your example ViewModel should do just fine. Another way that I've seen it accomplished is with a BaseViewModel<T> class that all ViewModels inherit from and takes the type of model and then exposes that as T Model { get; }

Is this a preferred way to forward an "extended" Model object to the View or are there patterns specifically engineered for this task?

The ViewModel has the responsibility of getting whatever models/data and keeping and modifying whatever UI state the View needs. Your example ViewModel seems to fit this responsibilty. However, I would only use a ViewModel class within a ViewModel if I'm also presenting the a "sub view" that goes along with that ViewModel. For instance, I would only use List<ColumnViewModel> if I was going to be looping through them and dynamically adding or including a control that's tied to the ColumnViewModel.

Would regular inheritance between the objects in Model and View Model work?

Although it could work, I think inheriting your ViewModel from the Model would be confusing. Plus, what if your Model is really a list of Model objects? Inheritance would be trickier in that case because you would need to make your base class a List<Model> and you would be exposing a bunch of unncessary methods to the View. I think wrapping is a better alternative.

Or should I create View Model classes that is tailored to fit the View and then map properties from the Model object to the View Model object?

ViewModels are generally tailored to fit the specific needs of a View. I tend to think of ViewModels as the code-behind for the view. The mapping of the model properties is generally done through the binding in the WPF View.

Will the garbage collector drop the model objects since there will be no more references to them after they have been mapped to the view model?

This all depends on your context, any references held by the objects in question and a variety of other factors. Generally, your view model should have the same life-time as your view and that includes the data. However, if there are specific performance concerns, you can always manually clear out the Model once it's been loaded.

Related Topic