Запустите приложение, выберите автомобиль Red Rider
(Ford
) и измените значение в поле Make (Производитель) на ModelT
. После того, как фокус покинет поле, появится декоратор ошибки красного цвета. Выберите в поле со списком автомобиль Kit
(Chevy
) и щелкните на кнопке Change Color, чтобы изменить его цвет на Pink
. Вокруг поля Color
незамедлительно появится декоратор ошибки красного цвета, но возле поля Make он будет отсутствовать. Измените значение в поле Make на Ford
и переместите фокус из этого поля; декоратор ошибки красного цвета не появляется!
Причина в том, что индексатор выполняется, только когда для свойства сгенерировано событие PropertyChanged
. Как обсуждалось в разделе "Система уведомлений привязки WPF" ранее в главе, событие PropertyChanged
инициируется при изменении исходного значения свойства объекта, что происходит либо через код (вроде обработчика события Click
для кнопки Change Color), либо через взаимодействие с пользователем (синхронизируется с помощью UpdateSourceTrigger
). При изменении цвета свойство Make не изменяется, а потому событие PropertyChanged
для него не генерируется. Поскольку событие не генерируется, индексатор не вызывается и проверка достоверности для свойства Make
не выполняется.
Решить проблему можно двумя путями. Первый предусматривает изменение объекта PropertyChangedEventArgs
, которое обеспечит обновление всех привязанных свойств, за счет передачи его конструктору значения string.Empty
вместо имени поля. Как упоминалось ранее, это заставит механизм привязки обновить OnPropertyChanged
со следующим кодом:
protected virtual void OnPropertyChanged([CallerMemberName]
string propertyName = "")
{
if (propertyName != nameof(IsChanged))
{
IsChanged = true;
}
//PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(string.Empty));
}
Теперь при выполнении того же самого теста текстовые поля Make и Color декорируются с помощью шаблона отображения ошибки, когда одно из них обновляется. Так почему бы ни генерировать событие всегда в такой манере? В значительной степени причиной является производительность. Вполне
Другое решение предполагает генерацию события PropertyChanged
для зависимого поля (полей), когда одно из полей изменяется. Недостаток такого приема в том, что вы (или другие разработчики, сопровождающие ваше приложение) должны знать о взаимосвязи между свойствами Make
и Color
через код проверки достоверности.
Интерфейс INotifyDataErrorInfo
Интерфейс INotifyDataErrorInfo
, появившийся в версии .NET 4.5, построен на основе интерфейса IDataErrorInfo
и предлагает дополнительные возможности для проверки достоверности. Конечно, возросшая мощь сопровождается дополнительной работой! По разительному контрасту с предшествующими приемами проверки достоверности, которые вы видели до сих пор, свойство привязки ValidatesOnNotifyDataErrors
имеет стандартное значение true
, поэтому добавлять его к операторам привязки не обязательно.
Интерфейс INotifyDataErrorInfo
чрезвычайно мал, но, как вскоре будет показано, для обеспечения своей эффективности требует написания порядочного объема связующего кода. Ниже приведено определение интерфейса INotifyDataErrorInfo
:
public interface INotifyDataErrorInfo
{
bool HasErrors { get; }
event EventHandler
ErrorsChanged;
IEnumerable GetErrors(string propertyName);
}
Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT