Интерфейс INotifyPropertyChanged
- это , реализованный с событиями. Интерфейс имеет только одного члена, PropertyChanged
, что является событием, на которое потребители могут подписаться.
Версия, опубликованная Ричардом, небезопасна. Вот как можно безопасно реализовать этот интерфейс:
public class MyClass : INotifyPropertyChanged
{
private string imageFullPath;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e);
}
protected void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public string ImageFullPath
{
get { return imageFullPath; }
set
{
if (value != imageFullPath)
{
imageFullPath = value;
OnPropertyChanged("ImageFullPath");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Обратите внимание, что это делает следующие вещи:
Абстрагирует методы уведомления об изменении свойства, чтобы вы могли легко применить это к другим свойствам;
Делает копию PropertyChanged
делегата до того, как попытается вызвать его (в противном случае это создаст состояние гонки).
Правильно реализует интерфейс INotifyPropertyChanged
.
Если вы хотите дополнительно создать уведомление для изменяемого специфического свойства , вы можете добавить следующий код:
protected void OnImageFullPathChanged(EventArgs e)
{
EventHandler handler = ImageFullPathChanged;
if (handler != null)
handler(this, e);
}
public event EventHandler ImageFullPathChanged;
Затем добавьте строку OnImageFullPathChanged(EventArgs.Empty)
после строки OnPropertyChanged("ImageFullPath")
.
Поскольку у нас есть .Net 4.5, существует CallerMemberAttribute
, который позволяет избавиться от жестко запрограммированной строки для имени свойства в исходном коде:
protected void OnPropertyChanged(
[System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public string ImageFullPath
{
get { return imageFullPath; }
set
{
if (value != imageFullPath)
{
imageFullPath = value;
OnPropertyChanged();
}
}
}