Настройка отображения данных с привязкой данных и WPF - Проверка ввода через IDataErrorInfo
ОГЛАВЛЕНИЕ
Проверка ввода через IDataErrorInfo
С появлением Microsoft .NET Framework 3.5 поддержка проверки ввода в WPF радикально улучшилась. Подход ValidationRule полезен для простых приложений, но реальные приложения имеют дело со всей сложностью реальных данных и бизнес-правил. Кодирование бизнес-правил в объекты ValidationRule не только привязывает этот код к платформе WPF, но также и не позволяет бизнес-логике быть там, где ей и положено быть: в бизнес-объектах!
У многих приложений имеется бизнес-слой, где все сложности обработки бизнес-правил заключены в набор бизнес-объектов. При компиляции в Microsoft .NET Framework 3.5 можно воспользоваться интерфейсом IDataErrorInfo, чтобы заставить WPF запрашивать бизнес-объекты о том, находятся ли они в допустимом состоянии или нет. Это избавляет от необходимости размещать бизнес-логику в объектах, отдельных от бизнес-слоя, и позволяет создавать бизнес-объекты, независимые от платформы интерфейса пользователя. Поскольку интерфейс IDataErrorInfo используется уже несколько лет, это также упрощает повторное использование бизнес-объектов из старых приложений Windows Forms или ASP.NET.
Предположим, что необходимо предоставить проверку для эпохи, выходящую за рамки простого обеспечения преобразуемости вводимого пользователем текста в тип данных свойства источника данных. Может иметь смысл не помещать дату начала эпохи в будущее, поскольку мы не знаем об эпохах, которые еще только предстоят. Также может иметь смысл требование, чтобы эпоха длилась не менее одной миллисекунды.
Эти типы правил подобны общей идее бизнес-логики в том, что оба они являются экземплярами правил области. Правила области лучше всего создавать в объектах, которые сохраняют их состояние: объектах области. В коде, приведенном наРис. 14, показан класс SmartEra, предоставляющий сообщения о выявленных проверкой ошибках через интерфейс IDataErrorInfo.
Рис. 14. IDataErrorInfo предоставляет сообщения о выявленных проверкой ошибках
public class SmartEra
: System.ComponentModel.IDataErrorInfo
{
public DateTime StartDate { get; set; }
public TimeSpan Duration { get; set; }#region IDataErrorInfo Members
public string Error
{
get { return null; }
}public string this[string property]
{
get
{
string msg = null;
switch (property)
{
case "StartDate":
if (DateTime.Now < this.StartDate)
msg = "Start date must be in the past.";
break;case "Duration":
if (this.Duration.Ticks == 0)
msg = "An era must have a duration.";
break;default:
throw new ArgumentException(
"Unrecognized property: " + property);
}
return msg;
}
}#endregion // IDataErrorInfo Members
}
Употребить поддержку проверки класса SmartEra из интерфейса пользователя WPF очень просто. Нужно лишь указать привязкам, что тем следует принять интерфейс IDataErrorInfo на объекте, к которому они привязаны. Это можно сделать одним из двух способов, как показано наРис. 15.
Рис. 15. Употребление логики проверки
<!-- START DATE -->
<TextBlock Grid.Row="0">Start Date:</TextBlock>
<TextBox Grid.Row="1">
<TextBox.Text>
<Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule />
<DataErrorValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox><!-- DURATION -->
<TextBlock Grid.Row="2">Duration:</TextBlock>
<TextBox
Grid.Row="3"
Text="{Binding
Path=Duration,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True}"
/>
Подобно тому, как правило ExceptionValidationRule можно добавить к коллекции ValidationRules привязки явно или неявно, правило DataErrorValidationRule можно добавить прямо к ValidationRules привязки, или же можно установить свойство ValidatesOnDataErrors на true. Оба подхода дают один и тот же конечный эффект – система привязки запрашивает интерфейс IDataErrorInfo источника данных на предмет выявленных проверкой ошибок.