Показанный далее интерфейс
IDataErrorInfo
содержит два свойства: индексатор и строковое свойство по имени
Error
. Следует отметить, что механизм привязки WPF не задействует свойство
Error
.
public interface IDataErrorInfo
{
string this[string columnName] { get; }
string Error { get; }
}
Вскоре вы добавите частичный класс
Car
, но сначала необходимо модифицировать класс в файле
Car.cs
, пометив его как частичный. Добавьте в папку
Models
еще один файл по имени
CarPartial.cs
. Переименуйте этот класс в
Car
, пометьте его как
partial
и обеспечьте реализацию классом интерфейса
IDataErrorInfo
. Затем реализуйте члены интерфейса
IDataErrorInfo
. Вот начальный код:
public partial class Car : IDataErrorInfo
{
public string this[string columnName] => string.Empty;
public string Error { get;}
}
Чтобы привязанный элемент управления мог работать с интерфейсом
IDataErrorInfo
, в выражение привязки потребуется добавить
ValidatesOnDataErrors
. Модифицируйте выражение привязки для текстового поля
Make
следующим образом (и аналогично обновите остальные конструкции привязки):
<TextBox Grid.Column="1" Grid.Row="1"
Text="{Binding Path=Make, <b>ValidatesOnDataErrors=True</b>}" />
После внесения изменений в конструкции привязки индексатор вызывается на модели каждый раз, когда возникает событие
PropertyChanged
. В качестве параметра
columnName
индексатора используется имя свойства из события. Если индексатор возвращает
string.Empty
, то инфраструктура предполагает, что все проверки достоверности прошли успешно и какие-либо ошибки отсутствуют. Если индексатор возвращает значение, отличающееся от
string.Empty
, тогда в свойстве для данного объекта присутствует ошибка, из-за чего каждый элемент управления, привязанный к этому свойству специфического экземпляра класса, считается содержащим ошибку. Свойство
HasError
объекта
Validation
устанавливается в
true
и активизируется декоратор
ErrorTemplate
для элементов управления, на которые повлияла ошибка.
Добавьте простую логику проверки достоверности к индексатору в файле
CorePartial.cs
. Правила проверки элементарны :
• если
Make
равно
ModelT
, то установить сообщение об ошибке в
"Too Old"
(слишком старая модель);
• если
Make
равно
Chevy
и
Color
равно
Pink
, то установить сообщение об ошибке в
$" {Make}'s don't come in {Color}"
(модель в таком цвете не поставляется).
Начните с добавления оператора
switch
для каждого свойства. Во избежание применения "магических" строк в операторах
case
вы снова будете использовать операцию
nameof
. В случае сквозного прохода через оператор
switch
возвращается
string.Empty
. Далее добавьте правила проверки достоверности. В подходящих операторах
case
реализуйте проверку значения свойства на основе приведенных выше правил. В операторе
case
для свойства
Make
первым делом проверьте, равно ли значение
ModelT
. Если это так, тогда возвратите сообщение об ошибке. В случае успешного прохождения проверки в следующей строке кода вызовите вспомогательный метод, который возвратит сообщение об ошибке, если нарушено второе правило, или
string.Empty
, если нет. В операторе
case
для свойства
Color
просто вызовите тот же вспомогательный метод. Ниже показан код:
public string this[string columnName]
{
get
{
switch (columnName)
{
case nameof(Id):
break;
case nameof(Make):
return Make == "ModelT"
? "Too Old"
: CheckMakeAndColor();
case nameof(Color):
return CheckMakeAndColor();
case nameof(PetName):
break;
}
return string.Empty;
}
}
internal string CheckMakeAndColor()
{
if (Make == "Chevy" && Color == "Pink")
{
return $"{Make}'s don't come in {Color}";
}
return string.Empty;
}
Запустите приложение, выберите автомобиль
Red Rider
(
Ford
) и измените значение в поле
Make (Производитель) на
ModelT
. После того, как фокус покинет поле, появится декоратор ошибки красного цвета. Выберите в поле со списком автомобиль
Kit
(
Chevy
) и щелкните на кнопке
Change Color, чтобы изменить его цвет на
Pink
. Вокруг поля
Color
незамедлительно появится декоратор ошибки красного цвета, но возле поля
Make он будет отсутствовать. Измените значение в поле
Make на
Ford
и переместите фокус из этого поля; декоратор ошибки красного цвета не появляется!