Stateful View Model

To create isolation between business logic and presentation, data should be removed from the view. The stateful view model pattern moves data into the view model using XAML data binding. This allows the view model to be tested without constructing a view, and it allows the view to change with minimal impact on the business logic.

Structure

Each view is data bound to a view model. The view model loads data from the model. It retains a copy of that data so that it can be displayed.

image

INotifyPropertyChanged

When the view data binds to properties, it stays in sync with their values. When the user enters a new value, the view sets the property. And when the property changes, the view gets the new value. To notify the view that a property has changed, the view model raises the PropertyChanged event. This event is defined in the INotifyPropertyChanged interface.

public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _name = "Steve";

    public string Name
    {
        get { return _name; }

        set
        {
            if (_name == value)
                return;

            _name = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }
}

Computed properties

A computed property will return a value based on one or more fields. When any of those fields changes, the view model raises property changed for the computed property as well.

public string Greeting
{
    get { return _greeting; }

    set
    {
        if (_greeting == value)
            return;

        _greeting = value;
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("Greeting"));
            PropertyChanged(this, new PropertyChangedEventArgs("Salutation"));
        }
    }
}

public string Salutation
{
    get { return string.Format("{0}, {1}!", _greeting, _name); }
}