Ответ 1
Я применил следующий подход, и он работает. В принципе, модель должна по праву записывать ошибки и добавлять их в словарь, даже если объект просто создан, и Пользователь еще не ввел текст. Поэтому я не изменил код модели или код проверки IDataErrorInfo. Вместо этого я просто установил свойство Validation.Error Template на {x: Null} изначально. Затем есть код для подключения события TextBox LostFocus, который изменяет шаблон Validation.Error обратно на то, что я использую. Чтобы добиться замены шаблонов и связать обработчик событий LostFocus со всеми TextBox в моем приложении, я использовал пару свойств зависимостей. Вот код, который я использовал.
Свойства зависимостей и код LostFocus:
public static DependencyProperty IsDirtyEnabledProperty = DependencyProperty.RegisterAttached("IsDirtyEnabled",
typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, OnIsDirtyEnabledChanged));
public static bool GetIsDirtyEnabled(TextBox target) {return (bool)target.GetValue(IsDirtyEnabledProperty);}
public static void SetIsDirtyEnabled(TextBox target, bool value) {target.SetValue(IsDirtyEnabledProperty, value);}
public static DependencyProperty ShowErrorTemplateProperty = DependencyProperty.RegisterAttached("ShowErrorTemplate",
typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false));
public static bool GetShowErrorTemplate(TextBox target) { return (bool)target.GetValue(ShowErrorTemplateProperty); }
public static void SetShowErrorTemplate(TextBox target, bool value) { target.SetValue(ShowErrorTemplateProperty, value); }
private static void OnIsDirtyEnabledChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) {
TextBox textBox = (TextBox)dependencyObject;
if (textBox != null) {
textBox.LostFocus += (s, e) => {
if ((bool) textBox.GetValue(ShowErrorTemplateProperty) == false) {
textBox.SetValue(ShowErrorTemplateProperty, true);
}
};
}
}
Если для свойства зависимостей IsDirtyEnabled установлено значение true, он использует обратный вызов для присоединения события TextBox LostFocus к обработчику. Обработчик просто изменяет прикрепленное свойство ShowErrorTemplate к true, которое, в свою очередь, запускает триггер стиля textbox, чтобы показать шаблон Validation.Error, когда TextBox теряет фокус.
Стили TextBox:
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationErrorTemplate}"/>
<Setter Property="gs:TextBoxExtensions.IsDirtyEnabled" Value="True" />
<Style.Triggers>
<Trigger Property="gs:TextBoxExtensions.ShowErrorTemplate" Value="false">
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
Это может показаться слишком большим количеством кода для простой вещи, но тогда я должен сделать это только один раз для всех текстовых ящиков, которые я использую.
С уважением, Nirvan.