Создайте вспомогательный метод для инициирования события
ErrorsChanged
(подобно инициированию события
PropertyChanged
):
private void OnErrorsChanged(string propertyName)
{
ErrorsChanged?.Invoke(this,
new DataErrorsChangedEventArgs(propertyName));
}
Как упоминалось ранее, метод
GetErrors
должен возвращать любые ошибки в словаре, когда в параметре передается пустая строка или
null
.
Если передается допустимое значение
propertyName
, то возвращаются ошибки, обнаруженные для указанного свойства. Если параметр не соответствует какому-либо свойству (или ошибки для свойства отсутствуют), тогда метод возвратит
null
.
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
return _errors.Values;
}
return _errors.ContainsKey(propertyName)
? _errors[propertyName]
: null;
}
Финальный набор вспомогательных методов будет добавлять одну или большее число ошибок для свойства либо очищать все ошибки для свойства (или всех свойств). Не следует забывать о вызове вспомогательного метода
Возникает вопрос: когда приведенный выше код активизируется? Механизм привязки прослушивает событие
ErrorsChanged
и обновляет пользовательский
интерфейс, если в коллекции ошибок для выражения привязки возникает изменение. Но код проверки по-прежнему нуждается в триггере для запуска. Доступны два механизма, которые обсуждаются далее.
Использование интерфейса INotifyDataErrorInfo для проверки достоверности
Одним из мест выполнения проверки на предмет ошибок являются блоки
set
для свойств, как демонстрируется в показанном ниже примере, упрощенном до единственной проверки на равенство свойства
Make
значению
ModelT
:
public string Make
{
get { return _make; }
set
{
if (value == _make) return;
_make = value;
if (Make == "ModelT")
{
AddError(nameof(Make), "Too Old");
}
else
{
ClearErrors(nameof(Make));
}
OnPropertyChanged(nameof(Make));
OnPropertyChanged(nameof(Color));
}
}
Основная проблема такого подхода состоит в том, что вам приходится сочетать логику проверки достоверности с блоками
set
для свойств, что делает код труднее в чтении и сопровождении.
Комбинирование IDataErrorInfo С INotifyDataErrorInfo для проверки достоверности
В предыдущем разделе было показано, что реализацию интерфейса
IDataErrorInfo
можно добавить к частичному классу, т.е. обновлять блоки
set
не понадобится. Кроме того, индексатор автоматически вызывается при возникновении события
PropertyChanged
в свойстве. Комбинирование
IDataErrorInfo
и
INotifyDataErrorInfo
предоставляет дополнительные возможности для проверки достоверности из
INotifyDataErrorInfo
, а также отделение от блоков
set
, обеспечиваемое
IDataErrorInfo
.
Цель применения
IDataErrorInfo
не в том, чтобы запускать проверку достоверности, а в том, чтобы гарантировать вызов кода проверки, который задействует
INotifyDataErrorInfo
, каждый раз, когда для объекта генерируется событие
PropertyChanged
. Поскольку интерфейс
IDataErrorInfo
не используется для проверки достоверности, необходимо всегда возвращать
string.Empty
из индексатора. Модифицируйте индексатор и вспомогательный метод