Click here to Skip to main content
13,006,530 members (61,615 online)
Click here to Skip to main content
Add your own
alternative version


59 bookmarked
Posted 1 Jan 2011

Automatic Implementation of INotifyPropertyChanged on POCO Objects

, 7 Jan 2011
Rate this:
Please Sign up or sign in to vote.
Implementing INotifyPropertyChanged automatically using a custom proxy generator


Using databinding in WPF obliges to use and implement the INotifyPropertyChanged interface. This task is usually boring, and even unsafe since properties have to be specified by name via simple strings. The property by string issue can be solved using lambda expression, so we can find some helper method that allows us some syntax sugar like...


...but we need to derive our ViewModel from some special class, and in any case we have to write some boring code every time we set a property. In order to avoid writing such things, we can use AOP to intercept property setters, but this usually involves some 3rd party library to add to our package, and sometimes this is an issue. In this article, we will see a solution to this problem using AOP, but so circumstantial that we will need just a few classes to embed in our solution in order to solve the problem.


Using INotifyPropertyChanged the plain vanilla way:

public class Customer :INotifyPropertyChanged
    private string name;

    public string Name
        get { return name; }
        set {
                 name = value;
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

With the AutoNotifyPropertyChange helper class, we can reduce the code above to this:

public class Customer 
    public virtual string Name

Simpler, isn't it?

In order to have the job done with the simple library we are talking about, the following requirements are mandatory to accomplish the result:

  1. ViewModel class has to be public
  2. Property to notify changes on must be public and virtual

Notification will occur only when property is changed through the public interface, proxy does not know anything about internal backing fields.

If a custom implementation of INotifyPropertyChanged is needed, we can pass to the proxy generator a class implementing INotifyPropertyChanged, but in this case we have to ensure the existence of a public or protected function called OnPropertyChanged(string propertyName) firing the event. The proxy generator assumes the function name and supposes the implementation works by firing the PropertyChange event in a proper and consistent way. Below is a model class that already implements INotifyPropertyChanged:

public class ModelSample:INotifyPropertyChanged
    public virtual int MyProperty1 { get; set; }
    public virtual double MyProperty2 { get; set; }
    public virtual DateTime MyProperty3 { get; set; }
    public float NoNotify { get; set; }
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    /* Since this class already implements INotifyPropertyChanged
     * having this function is mandatory
    protected virtual void OnPropertyChanged(string property)
        if (null != PropertyChanged)
            PropertyChanged(this, new PropertyChangedEventArgs(property));

The code below derives a class from Customer and wires the code to fire the PropertyChanged event every time we set a property value with a different value. Please note than the TypeFactory class is in a certain sense fault tolerant. If the interface is implemented, implementing the OnPropertyChanged(string propName) is mandatory. We can leverage fault tolerance in order to avoid notification for certain properties: just declare them as non virtual.

Customer model = Activator.CreateInstance(

How It Works

The AutoNotifyPropertyChange.TypeFactory class uses CodeDom to internally generate a subclass of the model and wire the code in the property setter. Class is internally compiled and returned as a type.

Let's see this example (POCO) class:

public class ClockViewModel
    public virtual int Hour { get; set; }
    public virtual int Minute { get; set; }
    public virtual int Second { get; set; }
    public virtual int Millisecond { get; set; }
    public virtual int Centiseconds { get { return Millisecond / 10; } }        

and see the autogenerated class (you will never have to use this code, it is just to show what happens behind the scenes):

namespace @__autonotifypropertychanged
    internal class @__autonotifyClockViewModel : Autonotify.Demo.ClockViewModel, 
        public override int Hour
                return base.Hour;
                if ((false == base.Hour.Equals(value)))
                    base.Hour = value;
        public override int Minute
                return base.Minute;
                if ((false == base.Minute.Equals(value)))
                    base.Minute = value;
        public override int Second
                return base.Second;
                if ((false == base.Second.Equals(value)))
                    base.Second = value;
        public override int Millisecond
                return base.Millisecond;
                if ((false == base.Millisecond.Equals(value)))
                    base.Millisecond = value;
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
            System.ComponentModel.PropertyChangedEventHandler handler;
            handler = this.PropertyChanged;
            if ((null != handler))
		new System.ComponentModel.PropertyChangedEventArgs(propertyName));

All the plumbing is done and you obtain a proxy implementing INotifyPropertyChange. You probably noted that the property "Centiseconds" is a read only calculated property, but in the generated code we see the event raising in the correct place: changing the milliseconds force a change to the Centiseconds property too. This is because internally the proxy generator investigates the code for every property getter in order to see if they use other property value, if so the property is considered to be dependent, proper events are fired. The inflector does not look at the code behavior, it simply assumes that if a getter is used then this will influence the result (this is correct while we are not using a property value inside a getter to produce some side effect, in this case a change event will be fired without reason, but in such a situation this will probably not be an issue).

To create the proxy, just write this:

var obj = Activator.CreateInstance( 
AutoNotifyPropertyChange.TypeFactory.AutoNotifier<ClockViewModel>() );

Autogenerated classes are cached internally, so asking many times for the same type does not require the code for the proxy to recreate and rebuild.

Points of Interest

The code is compiled as a DLL, but the classes for the proxy are just a few and can be merged into an existing solution code without any pain, there are no additional dependencies. In the sample application provided, a binding with a simple view is shown, using the ClockViewModel.


  • 30th December, 2010: Initial version
  • 4th January, 2011: Article updated


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

No Biography provided

You may also be interested in...


Comments and Discussions

QuestionNice Pin
jonhy0529-May-16 11:51
memberjonhy0529-May-16 11:51 
QuestionUsed it in Shielded; Thank you! Pin
Josip Bakić7-Dec-13 12:21
memberJosip Bakić7-Dec-13 12:21 
SuggestionVery nice work - inside is a markup extension so the DataContext can be easily set in xaml Pin
SBendBuckeye14-Feb-13 10:45
memberSBendBuckeye14-Feb-13 10:45 
You have written an excellent article. We try to always set our DataContexts in code, so I wrote a simple markup extension to enable the same.
using System;
using System.Windows;
using System.ComponentModel;
using System.Windows.Markup;
namespace Autonotify.Demo
    /// <summary>
    /// Markup extension to allow auto notification to be setup in xaml. Since the class will never actually be
    /// called using standard markup syntax (e.g. {}), we can ignore the best practice naming convention.
    /// </summary>
    public class DataContextGenerator : MarkupExtension
        public Type TargetType { get; set; }
        public override object ProvideValue(IServiceProvider serviceProvider)
            var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            var host = target.TargetObject as FrameworkElement;
            // Check for design mode or the clock will run in the designer.
            if (DesignerProperties.GetIsInDesignMode(host))
                return null;
                return Activator.CreateInstance(AutoNotifyPropertyChange.TypeFactory.AutoNotifier(TargetType));
It can then be used in xaml as below:
        <local:DataContextGenerator TargetType="local:ClockViewModel" />     

Have a great day!

GeneralMy vote of 5 Pin
gjvdkamp22-Feb-11 5:38
membergjvdkamp22-Feb-11 5:38 
GeneralHere is my take on it Pin
Siderite13-Jan-11 23:48
memberSiderite13-Jan-11 23:48 
GeneralPrivate models Pin
Oleg Shilo11-Jan-11 17:44
memberOleg Shilo11-Jan-11 17:44 
GeneralRe: Private models Pin
Felice Pollano12-Jan-11 20:33
memberFelice Pollano12-Jan-11 20:33 
GeneralRe: Private models Pin
Oleg Shilo13-Jan-11 13:04
memberOleg Shilo13-Jan-11 13:04 
GeneralIt would be nice if the type could be moved between assemblies. Pin
Siderite10-Jan-11 3:04
memberSiderite10-Jan-11 3:04 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Felice Pollano10-Jan-11 8:12
memberFelice Pollano10-Jan-11 8:12 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Siderite11-Jan-11 0:09
memberSiderite11-Jan-11 0:09 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Felice Pollano11-Jan-11 2:58
memberFelice Pollano11-Jan-11 2:58 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Siderite11-Jan-11 3:40
memberSiderite11-Jan-11 3:40 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Felice Pollano11-Jan-11 4:17
memberFelice Pollano11-Jan-11 4:17 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Siderite11-Jan-11 4:07
memberSiderite11-Jan-11 4:07 
GeneralRe: It would be nice if the type could be moved between assemblies. Pin
Felice Pollano11-Jan-11 4:18
memberFelice Pollano11-Jan-11 4:18 
GeneralMy vote of 5 Pin
Siderite10-Jan-11 2:54
memberSiderite10-Jan-11 2:54 
QuestionProxyGen - How can you create an anonymous delegate statement in CodeDom? Pin
Enrique Albert8-Jan-11 6:01
memberEnrique Albert8-Jan-11 6:01 
AnswerRe: ProxyGen - How can you create an anonymous delegate statement in CodeDom? Pin
Felice Pollano8-Jan-11 6:44
memberFelice Pollano8-Jan-11 6:44 
GeneralSuggestion for WPF binding projects Pin
Enrique Albert7-Jan-11 16:09
memberEnrique Albert7-Jan-11 16:09 
GeneralRe: Suggestion for WPF binding projects Pin
Felice Pollano7-Jan-11 22:00
memberFelice Pollano7-Jan-11 22:00 
GeneralRe: Suggestion for WPF binding projects Pin
Enrique Albert8-Jan-11 1:17
memberEnrique Albert8-Jan-11 1:17 
GeneralRe: Suggestion for WPF binding projects Pin
Felice Pollano8-Jan-11 2:15
memberFelice Pollano8-Jan-11 2:15 
GeneralMy vote of 5 Pin
rmx995-Jan-11 11:01
memberrmx995-Jan-11 11:01 
GeneralMy vote of 5 Pin
prasad024-Jan-11 4:59
memberprasad024-Jan-11 4:59 
GeneralGood job, but you've fallen into a trap Pin
Pete O'Hanlon4-Jan-11 0:35
mvpPete O'Hanlon4-Jan-11 0:35 
GeneralRe: Good job, but you've fallen into a trap Pin
Felice Pollano4-Jan-11 3:26
memberFelice Pollano4-Jan-11 3:26 
GeneralRe: Good job, but you've fallen into a trap Pin
Kjetil Klaussen4-Jan-11 10:43
memberKjetil Klaussen4-Jan-11 10:43 
QuestionDoes the vanilla setter really work? Pin
Jan_Gersl3-Jan-11 2:54
memberJan_Gersl3-Jan-11 2:54 
AnswerRe: Does the vanilla setter really work? Pin
Felice Pollano3-Jan-11 3:22
memberFelice Pollano3-Jan-11 3:22 
GeneralRe: Does the vanilla setter really work? Pin
germgerm10-Jan-11 2:58
membergermgerm10-Jan-11 2:58 
GeneralMy vote of 5 Pin
Abhishek Sur2-Jan-11 9:36
mvpAbhishek Sur2-Jan-11 9:36 
GeneralMy vote of 5 Pin
Marcelo Ricardo de Oliveira2-Jan-11 5:08
memberMarcelo Ricardo de Oliveira2-Jan-11 5:08 
QuestionHow does this play with Caliburn.Micro Pin
dtm1-Jan-11 14:27
memberdtm1-Jan-11 14:27 
AnswerRe: How does this play with Caliburn.Micro Pin
Felice Pollano1-Jan-11 20:59
memberFelice Pollano1-Jan-11 20:59 
GeneralHa to funny, mad timing Pin
Sacha Barber1-Jan-11 5:38
mvpSacha Barber1-Jan-11 5:38 
GeneralRe: Ha to funny, mad timing Pin
Felice Pollano1-Jan-11 7:49
memberFelice Pollano1-Jan-11 7:49 
GeneralRe: Ha to funny, mad timing Pin
Sacha Barber1-Jan-11 20:54
mvpSacha Barber1-Jan-11 20:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170628.1 | Last Updated 7 Jan 2011
Article Copyright 2011 by Felice Pollano
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid