ViewModelBase

Occasionally circumstances will prevent you from using ForView.Wrap() to wrap your view model. For example, the System.ComponentModel.DataAnnotations namespace contains several attributes that you could use to decorate your view model. The annotations give the view information on how to display and validate your properties. If you wrap it, the view cannot see these annotations.

You can pick-and-choose which view models can be wrapped automatically and which can be wrapped manually. If your View Model implements INotifyPropertyChanged, then ForView.Wrap() will let it pass through. So we only need to implement INotifyPropertyChanged on the view model that has annotations. We can do that with the ViewModelBase class.

public class PersonViewModel : ViewModelBase
{
}

The ViewModelBase class requires that we call the Get() method on every property getter. This injects the hook that Update Controls needs to track dependencies. The property depends upon everything referenced while getting it. When any of those things changes, ViewModelBase fires PropertyChanged events.

The Get() method takes a lambda expression that evaluates the property's value. The lambda expression looks like this: "() => value". For example:

public class PersonViewModel : ViewModelBase
{
    private Person _person;

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

    [Required]
    public string First
    {
        get { return Get(() => _person.First); }
        set { _person.First = value; }
    }
}

If the property is a collection, use GetCollection() instead.

public class ContactListViewModel : ViewModelBase
{
    private ContactList _contactList;

    public ContactListViewModel(ContactList contactList)
    {
        _contactList= contactList;
    }

    public IEnumerable<PersonViewModel> People
    {
        get
        {
            return GetCollection(() => _contactList.People
                .Select(p => new PersonViewModel(p)));
        }
    }
}

Hopefully you can let ForView.Wrap() handle data binding for you. But in those situations where you cannot, you could always use ViewModelBase.