#1,205 – Use CallerMemberName Attribute to Make INotifyPropertyChanged Implementation Cleaner

The INotifyPropertyChanged interface is central to using data binding in WPF. You typically create ViewModels containing properties that fire a PropertyChanged event whenever a property value changes. Implementing this plumbing over and over for every property can become tedious. This argues for a reusable pattern to make the per-property code cleaner.

Specifying string-based property names when raising the PropertyChanged event can also be error-prone. When, passing property names as string literals, a misspelled property name doesn’t lead to a compiler warning, but just a quiet data binding failure.

Below is a pattern you can use to make property change code cleaner. It relies on the CallerMemberName attribute, which can be used to default a method parameter to the name of a caller–the property name in this case.

We have a generic method that compares a new property value to the current value in the backing variable. If the value has changed, it assigns the new value and fires the property changed event.

        protected bool SetProp<T>(ref T backingField, T value, [CallerMemberName] string propName = null)
        {
            bool valueChanged = false;

            // Can't use equality operator on generic types
            if (!EqualityComparer<T>.Default.Equals(backingField, value))
            {
                backingField = value;
                RaisePropertyChanged(propName);
                valueChanged = true;
            }

            return valueChanged;
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        protected void RaisePropertyChanged(string propName)
        {
            if (!string.IsNullOrWhiteSpace(propName) && (PropertyChanged != null))
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

A standard property implementation can now look pretty clean. (Note: We’re not checking the return value of SetProp, but we could do that if we wanted to perform other logic when the property value changes).

        private Dog _selectedDog;
        public Dog SelectedDog
        {
            get { return _selectedDog; }
            set { SetProp(ref _selectedDog, value); }
        }

You would generally put this sort of code in a common base class that all of your ViewModel classes could inherit from.

About Sean
Software developer in the Twin Cities area, passionate about software development and sailing.

3 Responses to #1,205 – Use CallerMemberName Attribute to Make INotifyPropertyChanged Implementation Cleaner

  1. filhit says:

    SetProp always returns false now. The possible fix is to add valueChanged = true; after setting the backing field.

  2. Pingback: Dew Drop - April 25, 2017 (#2465) - Morning Dew

Leave a comment