这是我的建议,但我不太确定您的意思是“根据表单上的字段总结结果”。我认为我的建议应该允许你做任何你想做的事情。
我建议您使用 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;
}
}