我的表单绑定到一个实现IDataErrorInfo
的对象,并且它在逐个字段的基础上正确验证。我想基于表单上的字段而不是Error
的{{1}}属性来总结结果。有没有办法可以以某种方式循环控制并确定哪些控件无效?
谢谢!
答案 0 :(得分:0)
要执行此MVVM方式,您必须首先收集ViewModel中的所有错误。也就是说,找到所有属性都被验证为false,然后将所有这些属性的错误文本添加到集合/列表/数组,然后使用此集合/列表/数组在UI上显示错误摘要中的错误。
答案 1 :(得分:0)
以下是我的建议,但我不太清楚你的意思是“根据表格上的字段总结结果”。我认为我所建议的应该允许你做任何你想做的事。
我建议您使用IDataErrorInfo并使用您的对象及其字段而不是特定控件。在我所有ViewModel(你正在显示的数据)的基类中,我实现了像这样的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和 RaisePropertyChanged ,它是在Prism的 NotificationObject 类中实现的。 NotificationObject 类只是实现了 INotifyPropertyChanged ,并为您提供了一个名为RaisePropertyChanged的PropertyChanged(“PropertyName”)的重构安全版本,我传递了lamda表达式。
如果你不使用Prism,你可以简单地让SetError取两个字符串(属性,错误)。或者,自己实现PropertySupport.ExtractPropertyName方法以使用此重构安全版本。
e.g。
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;
}
}