IDataErrorInfo - 视图首次加载时忽略错误

13

我正在尝试使用IDataErrorInfo验证我的模型类,代码如下。

//Validators
public string this[string propertyName] {
    get {
        string error = null;

        if (propertyName == "Name") {
            error = ValidateName(); 
        }
        return error;
    }
}

这很好用,但是在视图首次加载时它已经包含了验证错误。是否有可能在视图首次加载时忽略/抑制验证错误?此外,在用户开始输入模型属性的数据之前,在视图加载时显示错误是否是一种常见做法。

问候, Nirvan。

编辑: 以下是我设置IDataErrorInfo的方式。

<TextBox Text="{Binding Name, ValidatesOnDataErrors=True}" Grid.Row="1" Grid.Column="1" />

4
好的,我会尽力进行翻译。以下是需要翻译的内容:See this question: https://dev59.com/QXI_5IYBdhLWcg3wK_o5请看这个问题:https://dev59.com/QXI_5IYBdhLWcg3wK_o5 - Alex Kofman
@AlexKofman 将此问题标记为重复。我已经完成了。 - MikroDel
4个回答

3
我采用了以下方法并且它有效。基本上,即使对象只是实例化而用户还没有输入任何文本,Model应该记录错误并将其列在字典中。因此我没有更改我的Model代码或IDataErrorInfo验证代码。相反,我只是最初将Validation.ErrorTemplate属性设置为{x:Null}。然后有一些代码来连接TextBox的LostFocus事件,将Validation.ErrorTemplate模板更改回我正在使用的内容。为了实现模板交换和将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,这反过来触发文本框的样式触发器以显示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。

Nirvan的解决方案很好,如果你将这段代码移动到一个基类(例如BaseControll)中,那么你可以从这个基类派生出所有的控件,并在所有的控件中拥有这种行为。 - Ralph de Ruijter
我知道已经过了一段时间,但我仍然面临着同样的问题。您的解决方案完美地解决了我的问题,我的问题是所有字段的验证错误消息是否相同--错误模板指向静态资源--谢谢! - hector-j-rivas

2
尝试在视图显示之后设置数据上下文。在我的情况下,这有所帮助。

1

你可以在ValidateName()方法中设置规则,视图只需显示错误 :) 我建议姓名是必填字段,应由用户填写,但您不喜欢视图首次加载时出现红色边框?

我使用两个不同的控件模板进行验证。errortemplate是普通模板,另一个用于必填字段(红色*)

这是我上次做法。


这肯定会隐藏视图中的错误,并且可能是一个可行的解决方案。然而,我仍然会等待一段时间,以防有比这更好的解决方案。谢谢。 - Jatin

1
你在 get 方法中抛出了异常吗?
public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        if (String.IsNullOrEmpty(value))
        {
            throw new ApplicationException("Customer name is mandatory.");
        }
    }
}

不,我没有抛出任何异常。我正在使用IDataErrorInfo接口来验证模型属性。 - Jatin
我的记忆是我必须使用ValidationRules仅在设置时进行错误检查。很抱歉,我现在无法访问该代码。 - paparazzo
无论如何,感谢您的努力。 - Jatin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接