How to implement Property Changed notification in WPF with a base ViewModel

Implement property changed notifications is tedious, there are some posts about how to implement it in a strongly-typed way. I decided combine that technique with a way to simplify the implementation of the setter.

The first what you need is a base class to inherit all your view models from, this class will have the necessary methods to raise the PropertyChanged event and to set the value of the property. Here is the base class that I use:

 

public abstract class ObservableObject : INotifyPropertyChanged

{

    protected ObservableObject()

    {

    }

 

    public event PropertyChangedEventHandler PropertyChanged;

 

    protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpresion)

    {

        var property = (MemberExpression)propertyExpresion.Body;

        VerifyPropertyExpression<T>(propertyExpresion, property);

        this.OnPropertyChanged(property.Member.Name);

    }

 

    protected void OnPropertyChanged(string propertyName)

    {

        if (this.PropertyChanged != null)

        {

            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

 

    protected void SetValue<T>(ref T refValue, T newValue, Expression<Func<T>> propertyExpresion)

    {

        if (!object.Equals(refValue, newValue))

        {

            refValue = newValue;

            this.OnPropertyChanged(propertyExpresion);

        }

    }

 

    protected void SetValue<T>(ref T refValue, T newValue, Action valueChanged)

    {

        if (!object.Equals(refValue, newValue))

        {

            refValue = newValue;

            valueChanged();

        }

    }

 

    [Conditional("DEBUG")]

    private void VerifyPropertyExpression<T>(

        Expression<Func<T>> propertyExpresion,

        MemberExpression property)

    {

        if (property.Member.GetType().IsAssignableFrom(typeof(PropertyInfo)))

        {

            throw new ArgumentException(string.Format(

                CultureInfo.CurrentCulture,

                "Invalid Property Expression {0}",

                propertyExpresion));

        }

 

        var instance = property.Expression as ConstantExpression;

        if (instance.Value != this)

        {

            throw new ArgumentException(string.Format(

                CultureInfo.CurrentCulture,

                "Invalid Property Expression {0}",

                propertyExpresion));

        }

    }

}

 

Basically when you implement a property that need property changed notification, all you need to do is the following:

 

private string notificable;

 

public string Notificable

{

    get { return this.notificable; }

    set { this.SetValue(ref this.notificable, value, () => this.Notificable); }

}

 

As you can see the implementation of the setter is very simple. There are some other cases when you need execute some logic if the value of the property is changed, but you do not really need property changed notification, for that reason there is a second overload of the SetValue method:

 

private string notificable;

 

public string Notificable

{

    get { return this.notificable; }

    private set { this.SetValue(ref this.notificable, value, this.OnNotificableChanged); }

}

 

private void OnNotificableChanged()

{

    // TODO seome logic here

}

 

As you can see is really easy to manage the notifications in this way.

2 Comments

  • Good work, I'll implement this logic in my future projects.
    Thanks!
    Shahnawaz

  • I solved the problems putting a dynamic object wrapper around the View Model. Wrapper is recursive and wraps also son classes, enumerables etc. It implements also IDataErrorInfo in a way to use dataannotations on the View Model. This way one can get both Validation and Changes Notification writing NO CODE at all. See the project on codeplex: http://validationtoolkit.codeplex.com/

Comments have been disabled for this content.