WPF/Silverlight and the INotifyPropertyChanged interface
Greetings and welcome to another post on refactorthis.net.
Today's topic is about an interface that all WPF and Silverlight developers have grown to love. The INotifyPropertyChanged interface facilitates notifying the data binding mechanisms of WPF and Silverlight of a property value change in your ViewModel to your view. Here is a simple illustration.
ClassicViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace INotifyPropertyChangedExample
{
public class ClassicViewModel
{
private string _personName;
public event PropertyChangedEventHandler PropertyChanged;
public string PersonName
{
get;
set
{
if (value != _personName)
_personName = value;
//No type safety here. If you make a mistake you will have problems.
OnPropertyChanged("PersonName");
}
}
public void OnPropertyChanged(string property)
{
if (property == null)
throw new ArgumentNullException("property");
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
When calling the method to raise the property changed event, you would need to pass the property name as a string to the handler. If you made any mistake in typing the property name, you would have to take time to debug your data binding.
A new and improved solution
C# 5.0 has provided some nifty compiler level attributes to assist with this scenario.
The [CallerMemberName] attribute of the System.Runtime.CompilerServices namespace can be used as an optional method parameter. When a method is called and there is no value specified for the parameter that is decorated with this attribute, you are provided with the name of the member that called the method. This takes the risk of a typing mishap out of your hands and allows you to rely on the compiler to provide this information to you! Here is an updated example!
ImprovedViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace INotifyPropertyChangedExample
{
public class ImprovedViewModel : INotifyPropertyChanged
{
private string _personName;
public event PropertyChangedEventHandler PropertyChanged;
public string PersonName
{
get { return _personName; }
set
{
if (value != _personName)
_personName = value;
OnPropertyChanged();
}
}
public void OnPropertyChanged([CallerMemberName] string property = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
As you can see, this is a great little addition to the C# language that will make your life a little easier.
I'd like to thank Patrick Steel for his article in MSDN magazine that inspired this article. Please check out his article for more uses of this and other new attributes and features of the C# 5.0 language.
http://visualstudiomagazine.com/Articles/2012/11/01/More-Than-Just-Async.aspx