Pass through view model

I will be speaking at the Dallas XAML user’s group on May 4. I’ll guide the group through the creation of a simple MVVM application to demonstrate why you want to use the pattern. This is a hands-on format, so bring your laptop. We will be using Visual Studio 2008 and WPF, so no special downloads will be required.

In preparing for this presentation, I’ve researched much of the MVVM advice currently available. Here are just some of the sources that I’ve found:

In almost every example, the presenter copies data from their Model into the View Model. Some don’t even have a Model at all! I, on the other hand, create pass-through View Models. My View Models don’t store any data. So either I’m doing it wrong, or my idea of MVVM is different from everybody else’s. Before I present the pattern to a room full of people with laptops, I’d like to know which.

Disconnected View Model
The typical example of a View Model example keeps a copy of its data. The properties work against local fields.

public class PersonViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value;
            FirePropetyChanged("FirstName");
            FirePropetyChanged("FullName");
        }
    }

    public string LastName
    {
        get
        {
            return _lastName;
        }
        set
        {
            _lastName = value;
            FirePropetyChanged("LastName");
            FirePropetyChanged("FullName");
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{1}, {0}", _firstName, _lastName);
        }
    }

    private void FirePropetyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Before you display the view, you have to copy the data into the view model. At some point later, you copy the data back out of the view model.

public class PersonViewModel

    //...

    public static PersonViewModel FromPerson(Person person)
    {
        return new PersonViewModel()
        {
            FirstName = person.FirstName,
            LastName = person.LastName
        };
    }

    public void ToPerson(Person person)
    {
        person.FirstName = _firstName;
        person.LastName = _lastName;
    }
}

Some of the experts just skip the model class altogether and go straight from their view model to the database or service.

Pass Through View Model

I prefer the pass through style. The view model stores no data.

public class PersonViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    public string FirstName
    {
        get
        {
            return _person.FirstName;
        }
        set
        {
            _person.FirstName = value;
            FirePropetyChanged("FirstName");
            FirePropetyChanged("FullName");
        }
    }

    public string LastName
    {
        get
        {
            return _person.LastName;
        }
        set
        {
            _person.LastName = value;
            FirePropetyChanged("LastName");
            FirePropetyChanged("FullName");
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{1}, {0}", _person.FirstName, _person.LastName);
        }
    }

    private void FirePropetyChanged(string propertyName)
    {
        if (PropertyChanged!= null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Instead of storing a copy of the Person data, this view model uses the storage that is in the actual Person model. There is no back-and-forth copying of data.

The advantages of pass through

I prefer the pass through style because it limits the number of moving parts in the application; in other words, it minimizes the “degrees of freedom”. Fewer moving parts means:

  1. Less code
  2. Fewer tests
  3. Fewer things that could break
  4. Simpler communication

If data exists in two places, then it will diverge. Data in one place will be more up-to-date than data in the other place. You have to write code to manage the divergence. That code needs to be tested. That code could break.

Many of the MVVM frameworks that the experts use have a mechanism for sending messages from one view model to another. This is necessary because each view model has its own copy of the data. But if each view model passes through to the same model object, then message passing is no longer necessary. The data model itself becomes the means of communication between view models.

The disadvantages of pass through

There is a trade-off between the disconnected and pass through styles. The pass through style does have some disadvantages:

  1. Harder to support Cancel
  2. Requires change notification from model
  3. Difficult to represent complex transformations

Some applications call for the modal dialog OK/Cancel metaphor. It is easier to implement this metaphor if you copy the data into a disconnected view model. If the user presses cancel, you just don’t copy the data back to the model.

While view models can use the data model to share data, they need to be notified of changes that other view models are making. That means that your view models not only implement INotifyPropertyChanged, they also subscribe to it. This can lead to a lot of bookkeeping code. Fortunately, there is a solution to this, but you have to use a third-party library.

Some transformations cannot be easily represented as a pass through. Maybe the objects in the data model need to be combined or regrouped in different ways. This regrouping cannot be easily done with pass through properties. A disconnected view model can make large scale transformations during the copying process.

None of the experts that I’ve studied make a distinction between disconnected view models and pass through view models. This is unfortunate, because the differences are significant. Where the advantages of a pass through view model outweigh the disadvantages, I find it to be an excellent choice. But before you can make that choice, you have to know that there is a choice to be made.

2 Responses to “Pass through view model”

  1. Craig Shoemaker Says:

    Michael:

    I think there is a lot of merit to what you are saying here. As always it depends on your situation, but pass through seems like a great way to simplify object interaction. I think I'll try to add this to the workshop.

    Best,

    Craig

  2. Den Says:

    Makes you think whether MVVM really "simplifies" things.

Leave a Reply

You must be logged in to post a comment.