#794 – A Better INotifyPropertyChanged Implementation

When implementing INotifyPropertyChanged, you need to pass the property name as a string in the PropertyChangedEventArgs object.  This can lead to subtle bugs in your code.  If you happen to spell the property name wrong, the client will be notified about the wrong (non-existent) property and the compiler won’t warn you that there is a problem.

If you use C# 5.0 and target the .NET Framework 4.5, there’s an easier way.  You can use the CallerMemberName attribute to avoid having to pass the property name as a string.

        private int age;
        public int Age
        {
            get { return age; }
            set
            {
                if (age != value)
                {
                    age = value;
                    RaisePropertyChanged();
                }
            }
        }

        //-- INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged([CallerMemberName]string prop = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }

Don’t forget to include:

using System.Runtime.CompilerServices;
Advertisements

#793 – Being Notified When an Object’s Properties Change, Part II

Once you’ve implemented the INotifyPropertyChanged interface in a class, you can subscribe to the PropertyChanged event for an instance of your class.  Assuming that you’ve implemented INotifyPropertyChanged properly, the event will fire whenever any property value in the object changes.

The code below assumes that the Dog class implements INotifyPropertyChanged.

        static void Main(string[] args)
        {
            Dog d = new Dog("Bob", 5);

            d.PropertyChanged += d_PropertyChanged;

            d.Name = "Bob Jr.";
            d.AgeThisDog();
            d.Age = 10;
        }

        static void d_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            Console.WriteLine(string.Format("Property {0} just changed", e.PropertyName));
        }

793-001

The PropertyChanged event handler receives an instance of a PropertyChangedEventArgs object, which just contains a PropertyName property that tells you which property changed.  It pass any information about either the old or the new values of the property.  The assumption is that client code can read the updated property value on their own.

#792 – Being Notified When an Object’s Properties Change, Part I

If you write a class, there’s a pattern that you can implement, to let users of your class know when a property value changes.  This pattern is implemented by implementing the INotifyPropertyChanged in your class.

The purpose of this pattern is to let client code know that some property value has changed, in situations where that code didn’t initiate the change.  For example, this pattern is used in data binding.

Below is an example of a class that implements INotifyPropertyChanged.  The class defines an event that is fired whenever any property value changes.

    public class Dog : INotifyPropertyChanged
    {
        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }

        private int age;
        public int Age
        {
            get { return age; }
            set
            {
                if (age != value)
                {
                    age = value;
                    RaisePropertyChanged("Age");
                }
            }
        }

        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public void AgeThisDog()
        {
            Age++;
        }

        //-- INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }

Part II of this topic will show how client code can use this new event.