Чтение онлайн

на главную - закладки

Жанры

Язык программирования C#9 и платформа .NET5
Шрифт:

public class Car : INotifyPropertyChanged

{

// Для краткости код не показан.

public event PropertyChangedEventHandler PropertyChanged;

}

Событие

PropertyChanged
принимает объектную ссылку и новый экземпляр класса
PropertyChangedEventArgs
:

PropertyChanged?.Invoke(this,

new PropertyChangedEventArgs("Model"));

Первый

параметр представляет собой объект, который инициирует событие. Конструктор класса
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. Изменение немедленно отобразится в пользовательском интерфейсе. Первая проблема решена!

Использование операции nameof

В версии 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
зависит от личных предпочтений.

Наблюдаемые коллекции

Следующей проблемой, которую необходимо решить, является обновление пользовательского интерфейса при изменении содержимого коллекции, что достигается путем реализации интерфейса

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

Использование класса ObservableCollection<T>

К счастью, существует намного более легкий способ, чем создание собственных классов коллекций. Класс

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

private readonly IList<Car> _cars =

new ObservableCollection<Car>;

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

Реализация флага изменения

Еще одним преимуществом наблюдаемых моделей является способность отслеживать изменения состояния. Отслеживать флаги изменения (т.е. когда изменяется одно и более значений объекта) в WPF довольно легко. Добавьте в класс

Car
свойство типа
bool
по имени
IsChanged
. Внутри его блока
set
вызовите метод
OnPropertyChanged
, как поступали с другими свойствами класса
Car
.

Поделиться:
Популярные книги

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Покоритель Звездных врат

Карелин Сергей Витальевич
1. Повелитель звездных врат
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Покоритель Звездных врат

Совок-8

Агарев Вадим
8. Совок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совок-8

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Король Масок. Том 1

Романовский Борис Владимирович
1. Апофеоз Короля
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Король Масок. Том 1

Ищу жену для своего мужа

Кат Зозо
Любовные романы:
любовно-фантастические романы
6.17
рейтинг книги
Ищу жену для своего мужа

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Темный Охотник 2

Розальев Андрей
2. Темный охотник
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник 2

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Обыкновенные ведьмы средней полосы

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Обыкновенные ведьмы средней полосы

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Идущий в тени 4

Амврелий Марк
4. Идущий в тени
Фантастика:
боевая фантастика
6.58
рейтинг книги
Идущий в тени 4