Basic MVVM Base class / INotifyPropertyChanged implementation

A while back, (OK, a long while back), I promised an article on how to create a MMVM view model base class.  This class will implement the INotifyPropertyChanged interface, and add some common sugar on top of it to make it really easy to use.

In all project types that use XAML, you can bind items in the UI to properties in the view model. The purpose of INotifyPropertyChanged is to notify those binding of when the underlying property changes so the updated values can be pulled in. It has one item, an event called PropertyChanged. However, just adding an event is not super helpful. So here’s an example of a base class that adds a bit more.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace MVVMBase
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        //The interface only includes this evennt
        public event PropertyChangedEventHandler PropertyChanged;

        //Common implementations of SetProperty
        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null)
        {
            bool propertyChanged = false;

            //If we have a different value, do stuff
            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                field = value;
                OnPropertyChanged(name);
                propertyChanged = true;
            }

            return propertyChanged;
        }

        //The C#6 version of the common implementation
        protected void OnPropertyChanged([CallerMemberName]string name = null)
        {
           PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

So what does it do:

  1. Implement INotifyPropertyChanged – yup, the event is there, job done.
  2. Creates a handy SetProperty method that does the following:
    1. Takes the property name, a reference to it’s backing field and the new value
    2. Checks if the new value is actually different
    3. If so it updates the backing field and invokes the property changed event
    4. Returns a value to indicate if the property actually changed
  3. Creates an OnPropertyChanged method (this is often also called RaisePropertyChanged) that can be used to force the PropertyChanged event to fire for a given property.

Now that I’ve got this, using it is pretty simple. First, make you view models inherit from this. Then write your properties this way:

private bool _messageReady;
public bool MessageReady
{
    get { return _messageReady; }
    set { SetProperty(ref _messageReady, value); }
}

Note that although SetProperty is generic, you don’t have to pass in a Type, and although it takes 3 propereties, and the third is the name of the property is being changed, you don’t have to as the default is set to the CallerMemberName attribute. Of course, you can do both and if you needed to do some thing where you set the property indirectly as part of some other method, you could then call SetProperty<bool>(ref _messageReady, true, “MessageReady”);

Some Properties are getter only and depend on the values of other properties and fields in the class. This is a place where that OnPropertyChanged method is useful.

private bool _messageReady; 
public bool MessageReady 
{ 
    get { return _messageReady; } 
    set 
    { 
        if (SetProperty(ref _messageReady, value))
        {
            OnPropertyChanged(() => BackgroundColor);
        }
    } 
}

public Color BackgroundColor
{
    get { return MessageReady ? Colors.Green : Colors.White.
}

In this example, we have a property called BackgroundColor that is normally white, but becomes green when a message is ready. But as it’s just a getter, how does our UI know when it’s value changes? We call OnPropertyChanged for BackgroundColor when the MessageReady property is updated.

So that’s a brief tour of a view model base class.  If you look around, you will find others who may have more, or that have different implementations of these methods. For me, this is the basics of what you need – an implementation of INotifyPropertyChanged that you only need to make once, and that makes updating bound properties easy to do.

CodeSample: MVVMBase.zip

3 comments

  1. Great stuff! Just one question: In your last example, you’re calling OnPropertyChanged(string) by passing a lambda:

    OnPropertyChanged(() => BackgroundColor);

    But when I try that approach in a similar class I created, Intellisense won’t let me do it, saying “Cannot convert lambda expression to type ‘string’ because it is not a delegate type. Argument type ‘lambda expression’ is not assignable to type ‘string.’ So are you using a helper class for this functionality?

    Like

    • Hi Ken, Thanks for your feedback and question.

      Yes, the original was using a helper method, that I forgot to include, but additionally, I have largely ditched that approach, to now using something much simpler for keeping raw strings out.
      It should now read:
      OnPropertyChanged(nameof(BackgroundColor));

      Thanks C#6.0. No helpers needed.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.