Первый параметр представляет собой объект, который инициирует событие. Конструктор класса PropertyChangedEventArgs принимает строку, указывающую свойство, которое было изменено и нуждается в обновлении. Когда событие инициировано, механизм привязки ищет элементы управления, привязанные к именованному свойству данного объекта. В случае передачи конструктору PropertyChangedEventArgs значения String.Empty обновляются все привязанные свойства объекта.

Вы сами управляете тем, какие свойства вовлечены в процесс автоматического обновления. Автоматически обновляться будут только те свойства, которые генерируют событие PropertyChanged внутри блока set. Обычно в перечень входят все свойства классов моделей, но в зависимости от требований приложения некоторые свойства можно опускать. Вместо инициирования события PropertyChanged непосредственно в блоке set для каждого задействованного свойства распространенный подход предусматривает написание вспомогательного метода (как правило, называемого OnPropertyChanged()), который генерирует событие от имени свойств обычно в базовом классе для моделей. Добавьте в класс Car следующий метод:

protected void OnPropertyChanged([CallerMemberName] string propertyName = "")

{

  PropertyChanged?.Invoke(this,

    new PropertyChangedEventArgs(propertyName));

}

Модифицируйте каждое автоматическое свойство класса Car, чтобы оно имело полноценные блоки get и set, а также поддерживающее поле. В случае если значение изменилось, вызовите вспомогательный метод OnPropertyChanged(). Вот обновленное свойство Id:

private int _id;

public int Id

{

  get => _id;

  set

  {

    if (value == _id) return;

    _id = value;

    OnPropertyChanged();

  }

}

Проделайте аналогичную работу со всеми остальными свойствами в классе и снова запустите приложение. Выберите автомобиль и щелкните на кнопке Change Color. Изменение немедленно отобразится в пользовательском интерфейсе. Первая проблема решена!

<p id="AutBody_Root1263"><strong>Использование операции nameof</strong></p>

 В версии C# 6 появилась операция nameof, которая возвращает строковое имя переданного ей элемента. Ее можно применять в вызовах метода OnPropertyChanged() внутри блоков set, например:

public string Color

{

  get { return _color; }

  set

  {

    if (value == _color) return;

    _color = value;

    OnPropertyChanged(nameof(Color));

  }

}

Обратите внимание на то, что в случае использования операции nameof удалять атрибут [CallerMemberName] из метода OnPropertyChanged() необязательно (хотя он становится излишним). В конце концов, выбор между применением операции nameof или атрибута CallerMemberName зависит от личных предпочтений.

<p id="AutBody_Root1264"><strong>Наблюдаемые коллекции</strong></p>

 Следующей проблемой, которую необходимо решить, является обновление пользовательского интерфейса при изменении содержимого коллекции, что достигается путем реализации интерфейса INotifyCollectionChanged. Подобно INotifyPropertyChanged данный интерфейс открывает доступ к единственному событию CollectionChanged. В отличие от INotifyPropertyChanged реализация интерфейса INotifyCollectionChanged вручную предполагает больший объем действий, чем просто вызов метода в блоке set свойства. Понадобится создать реализацию полного списка объектов и генерировать событие CollectionChanged каждый раз, когда он изменяется.

<p id="AutBody_Root1265"><strong>Использование класса ObservableCollection<t></t></strong></p>

К счастью, существует намного более легкий способ, чем создание собственных классов коллекций. Класс ObservableCollection реализует интерфейсы INotifyCollectionChanged, INotifyPropertyChanged и Collection и входит в состав .NET Core. Никакой дополнительной работы делать не придется. Чтобы продемонстрировать его применение, добавьте оператор using для пространства имен System.Collections.ObjectModel и модифицируйте закрытое поле _cars следующим образом:

private readonly IList _cars =

  new ObservableCollection();

Снова запустите приложение и щелкните на кнопке Add Car. Новые записи будут должным образом появляться.

<p id="AutBody_Root1266"><strong>Реализация флага изменения</strong></p>
Перейти на страницу:

Похожие книги