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

时间:2012-04-17 11:15:41

标签: wpf validation idataerrorinfo wpf-4.0

我正在尝试使用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 个答案:

答案 0 :(得分:3)

我采用了以下方法,但它确实有效。基本上,模型应该正确地记录错误并将它们列在字典中,即使该对象刚刚被实例化并且用户尚未输入任何文本。所以我没有更改我的Model代码或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样式:

<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。

答案 1 :(得分:2)

尝试在显示视图后设置数据上下文。

就我而言,这有帮助。

答案 2 :(得分:1)

你是否在get中抛出异常?

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        if (String.IsNullOrEmpty(value))
        {
            throw new ApplicationException("Customer name is mandatory.");
        }
    }
}

答案 3 :(得分:1)

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

我使用两个不同的控制模板进行验证.errortemplate正常的一个和一个必填字段(红色*)

thats我最后一次这样做的方式。