0

My form is bound to an object that implements IDataErrorInfo and it validates correctly on a field by field basis. I would like to have some way to summarize the results based on the fields on the form, and not the Error property of IDataErrorInfo. Is there a way I can loop through the controls somehow and determine which controls are invalid?

Thanks!

4

2 回答 2

0

这是我的建议,但我不太确定您的意思是“根据表单上的字段总结结果”。我认为我的建议应该允许你做任何你想做的事情。

我建议您使用 IDataErrorInfo 并使用您的对象及其字段而不是特定控件。在我所有 ViewModels 的基类(您正在显示的数据)中,我像这样实现 IDataErrorInfo

private Dictionary<string, string> errors = new Dictionary<string, string>();

public virtual string Error
{
    get { return String.Join(Environment.NewLine, errors); }
}

public bool HasErrors
{
    get
    {
        return errors.Count > 0;
    }
}

public string this[string propertyName]
{
    get
    {
        string result;
        errors.TryGetValue(propertyName, out result);
        return result;
    }
}

protected void SetError<T>(Expression<Func<T>> prop, String error)
{
    String propertyName = PropertySupport.ExtractPropertyName(prop);

    if (error == null)
        errors.Remove(propertyName);
    else
        errors[propertyName] = error;

    OnHasErrorsChanged();
}

protected string GetError<T>(Expression<Func<T>> prop, String error)
{
    String propertyName = PropertySupport.ExtractPropertyName(prop);

    String s;
    errors.TryGetValue(propertyName, out s);
    return s;
}

protected virtual void OnHasErrorsChanged()
{

}

然后,我可以实现这样的属性,用于数据绑定来存储验证错误:

public String ProjectName
{
    get { return projectName; }
    set
    {
        if (value != projectName)
        {
            projectName = value;
            SetError(() => ProjectName, ValidateProjectName());
            RaisePropertyChanged(() => this.ProjectName);
        }
    }
}

获取任何字段的错误

String error = GetError( () => SomeField ); // OR
String error = this["SomeField"];

或者您可以使用错误来获取所有错误的列表


注意在这个例子中,我使用了我实现的 SetError 和在 Prism 的NotificationObject类中实现的RaisePropertyChanged 。NotificationObject类简单地实现了INotifyPropertyChanged并为您提供了一个名为 RaisePropertyChanged 的​​ PropertyChanged("PropertyName") 的重构安全版本,我通过 lamda 表达式。

如果你不使用 Prism,你可以简单地让 SetError 接受两个字符串(属性,错误)。或者,您自己实现 PropertySupport.ExtractPropertyName 方法以使用此重构安全版本。

例如

public static class PropertySupport
{
    public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpresssion)
    {
        if (propertyExpresssion == null)
        {
            throw new ArgumentNullException("propertyExpression");
        }

        var memberExpression = propertyExpresssion.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
        }

        var property = memberExpression.Member as PropertyInfo;
        if (property == null)
        {
            throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
        }

        var getMethod = property.GetGetMethod(true);
        if (getMethod.IsStatic)
        {
            throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
        }

        return memberExpression.Member.Name;
    }
}
于 2013-05-16T14:20:09.187 回答
0

要执行这种 MVVM 方式,您必须首先收集 ViewModel 中的所有错误。也就是说,找出哪些所有属性都被验证为假,然后将所有此类属性的错误文本添加到集合/列表/数组中,然后使用此集合/列表/数组在 UI 上的错误摘要中显示错误。

于 2013-05-16T06:26:50.390 回答