我采用了以下方法并且它有效。基本上,模型应该正确地记录错误并将它们列在字典中,即使对象刚刚被实例化并且用户还没有输入任何文本。所以我没有更改我的模型代码或 IDataErrorInfo 验证代码。相反,我最初只是将 Validation.Error 模板属性设置为 {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 模板。
文本框样式:
<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>
对于一件简单的事情来说,这似乎代码太多了,但是对于我正在使用的所有文本框,我只需执行一次。
问候,尼尔文。