.NET has provided two Interfaces used in specifying the monitoring of changes to Properties since version 2.0: INotifyPropertyChanging, and INofifyPropertyChanged.
Beginning in .NET 4.5 a new feature was added for avoiding having to hard code the name of the property changing/changed into the call:
.NET 2.0 to .NET 3.5:
using System.ComponentModel;
namespace YourNameSpace
{
public class PropertyNotificationDemo : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanging(string data)
{
if (PropertyChanging != null) PropertyChanging(this, new PropertyChangingEventArgs(data));
}
private void NotifyPropertyChanged(string data)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(data));
}
private string someString;
public string SomeString
{
get { return someString; }
set
{
if (value != someString)
{
NotifyPropertyChanging("SomeString");
someString = value;
}
}
}
private string anotherString;
public string AnotherString
{
get { return anotherString; }
set
{
if (value != anotherString)
{
anotherString = value;
NotifyPropertyChanged("AnotherString");
}
}
}
}
}
You use these Event declarations that implement the Property Changing/Changed facilities by creating instances of the Class and subscribing to the Events like you would any other custom Event:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace YourNameSpace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
PropertyNotificationDemo pnd = new PropertyNotificationDemo();
private void Form1_Load(object sender, EventArgs e)
{
pnd.PropertyChanging += pnd_PropertyChanging;
pnd.PropertyChanged += pnd_PropertyChanged;
pnd.SomeString = "hello";
pnd.AnotherString = "goodbye";
}
private void pnd_PropertyChanging(object sender, PropertyChangingEventArgs e)
{
MessageBox.Show(string.Format("{0} is changing", e.PropertyName));
}
private void pnd_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MessageBox.Show(string.Format("{0} is changed", e.PropertyName));
}
}
}
Beginning with .NET 4.5: the 'CallerMemberName Attribute was added: now the Class that uses the new Property Changed/Changing requires:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace YourNameSpace
{
public class PropertyNotificationDemo : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanging([CallerMemberName] string propertyName = "")
{
if (PropertyChanging != null) PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string someString;
public string SomeString
{
get { return someString; }
set
{
if (value != someString)
{
NotifyPropertyChanging();
someString = value;
}
}
}
private string anotherString;
public string AnotherString
{
get { return anotherString; }
set
{
if (value != anotherString)
{
anotherString = value;
NotifyPropertyChanged();
}
}
}
}
}
And, the EventHandlers in the Form that creates an instance of, and uses, this Class look like this:
private void pnd_PropertyChanging(object sender, PropertyChangingEventArgs e)
{
MessageBox.Show(string.Format("{0} is changing", e.PropertyName));
}
private void pnd_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MessageBox.Show(string.Format("{0} is changed", e.PropertyName));
}