Показанный далее интерфейс 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 следующим образом (и аналогично обновите остальные конструкции привязки):
Text="{Binding Path=Make, ValidatesOnDataErrors=True}" />
После внесения изменений в конструкции привязки индексатор вызывается на модели каждый раз, когда возникает событие 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;
}