Какой лучший способ вызвать событие INotifyPropertyChanged PropertyChanged?
Когда вы реализуете интерфейс INotifyPropertyChanged, вы отвечаете за вызов события PropertyChanged каждый раз, когда свойство обновляется в классе.
Это обычно приводит к следующему коду:
public class MyClass: INotifyPropertyChanged
private bool myfield;
public bool MyField
{
get { return myfield; }
set
{
if (myfield == value)
return;
myfield = value;
OnPropertyChanged(new PropertyChangedEventArgs("MyField"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler h = PropertyChanged;
if (h != null)
h(this, e);
}
}
Это 12 строк для каждого свойства.
Было бы намного проще, если бы можно было украсить автоматические свойства следующим образом:
[INotifyProperty]
public double MyField{ get; set; }
Но, к сожалению, это невозможно (см. этот пост в msdn, например)
Как я могу уменьшить количество кода, необходимого для каждого свойства?
Ответы
Ответ 1
Собственно, это всего 3-4 строки за собственность; другие строки амортизируются по всем "уведомляющим" свойствам:
class Person : INotifyPropertyChanged
{
#region INotifyPropertyChanged: Shared bit
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
#endregion
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (_firstName == value)
return;
_firstName = value;
OnPropertyChanged(new PropertyChangedEventArgs("FirstName"));
}
}
// Ditto for other properties
}
Вы можете попробовать что-то вроде следующего, которое разделяет еще одну нагрузку:
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { SetNotifyingProperty("FirstName", ref _firstName, value); }
}
private void SetNotifyingProperty<T>(string propertyName,
ref T field, T value)
{
if (value.Equals(field))
return;
field = value;
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
Ответ 2
Сейчас я пишу это в своем классе:
//AUTOGENERATE INotifyProperty
private bool myfield;
И я написал небольшой инструмент, который генерирует весь необходимый код свойства в частичном классе.
Это отнюдь не элегантное решение, но оно работает:)
Ответ 3
Наиболее целесообразно передать на аутсорсинг.
Напишите класс (ObservableObject) со следующим кодом:
class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Все классы, производные от этого класса, могут получить доступ к методу, благодаря защищенному.
Пример:
class Example : ObservableObject
{
//propfull
private string name;
public string Name
{
get {return name;}
set
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
}