Raising PropertyChanged for all properties

When working with WPF (Windows Presentation Foundation) you will often face the need to update the user interface based on some changes that took place in your view model. This is most of the time achieved by implementing the INotifyPropertyChanged interface and raising the PropertyChanged event every time your data-bound properties change their value.

You are most likely to find code that looks something like this:

public class PersonViewModel : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   private string _firstName;
   public string FirstName
   {
      get { return _firstName; }
      set
          {
            _firstName = value;

            if (PropertyChanged != null)
               PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
           }
   }
}

Note: there are nicer ways of achieving this, but they fall out of the scope of this post.

Depending on your scenario, the above pattern can become less elegant if most of the properties of your view model change at once. In this case, polluting the view model with code that raises the PropertyChanged event for each property is undesirable, and a better way to notify that all properties have changed their value is needed. This is the case when you can use a documented obscurity of WPF: raising the PropertyChanged event and supplying null or string.Empty for the propertyName constructor parameter of PropertyChangedEventArgs.

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

The readability of the above code sample is astonishing, what on earth new PropertyChangedEventArgs(null) is supposed to mean? When code reviewing such code, my “bug-detecting” sensors would go wild (ArgumentNullException, NullReferenceException, etc), however, luckily the whole thing is wrapped around a NotifyAllPropertiesHaveChanged method, which would help calm things down a bit, but it would still fall short in convincing a non-believer that the above implementation is finished, or it is just a stub.

A nicer implementation would be to create a new class AllPropertiesChangedEventArgs  that inherits the PropertyChangedEventArgs class.

public class AllPropertiesChangedEventArgs : PropertyChangedEventArgs
{
   public AllPropertiesChangedEventArgs()
      : base(null)
   { }
}

The new class will isolate the obscure way of raising the PropertyChanged event, and will also make the code more readable and explicit.

public void NotifyAllPropertiesHaveChanged()
{
   if (PropertyChanged != null)
         PropertyChanged(this, new AllPropertiesChangedEventArgs());
}

One comment on “Raising PropertyChanged for all properties

  1. Tom September 14, 2017 00:12

    IMHO, this “nicer implementation” is just “putting lipstick on a pig”. ;) I think the more likely and more costly costs of having all Subscribers of all Properties Calling the latters’ Getters when in the future, a Property is added that’s *undesired* to be included in the Calls outweighs the less likely costs of forgetting to add a PropertyChanged Call to a shared Method that calls it for each *desired* Property by looping through a list that *explicitly* itemizes the list of names of *desired* Properties and does so via (and with the added benefits of) Compiler-check-able / “Find All References”-able NameOf calls esp. if a DEBUG-mode only Instantiation-time-only Method compares that list to the current Reflection-generated list of Properties with known exceptions *explicitly* ignored. The reasons to avoid a PropertyChanged Call with a Null Parameter are similar to the reasons to avoid the “Select *” Statement which is a SQL Anti-Pattern.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>