目前我正在开发.net 4.5 wpf MVVM应用程序,其验证系统由INotifyDataErrorInfo处理。在应用程序的某个时刻,我必须检查是否有任何验证错误,目前它是这样做的:
public class RootViewModel : BindableBase
{
//class code
if (designInformation.Technology == Technology.CVT)
{
if (designInformation.HasErrors) return;
if (InfoInputViewModel.TrafoProperties.HasErrors) return;
if (InfoInputViewModel.CapacitorVoltageTransformerViewModel.CapacitorVoltageDivider.HasErrors) return;
if (InfoInputViewModel.CapacitorVoltageTransformerViewModel.IntermediateVoltageTransformer.HasErrors) return;
if (SpecialDesignViewModel.SpecialDesignInformation.HasErrors) return;
foreach (var item in InfoInputViewModel.SecondaryWindings.WindingsCollection)
{
if (item.HasErrors) return;
}
performCalculationsCVT();
}
}
我正在寻找一种方法来通过立即从模型中获取所有错误来简化此代码,但不知道从哪里开始解决此问题。
Bellow是我使用的INotifyDataErrorInfo接口的实现。
public class ValidableBase : BindableBase, INotifyDataErrorInfo
{
protected readonly Dictionary<string, ICollection<string>>
_validationErrors = new Dictionary<string, ICollection<string>>();
#region INotifyDataErrorInfo Implementation
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
protected void RaiseErrorsChanged(string propertyName)
{
if (ErrorsChanged != null)
ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
}
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(propertyName) || !_validationErrors.ContainsKey(propertyName))
return null;
return _validationErrors[propertyName];
}
public bool HasErrors
{
get { return _validationErrors.Count > 0; }
}
public void AddError(string propertyName, string message)
{
if (_validationErrors.ContainsKey(propertyName))
{
string value = _validationErrors[propertyName].First();
value += Environment.NewLine;
value += message;
_validationErrors[propertyName] = new List<string> { value };
}
else
_validationErrors[propertyName] = new List<string> { message };
RaiseErrorsChanged(propertyName);
}
public void RemoveError(string propertyName)
{
_validationErrors.Remove(propertyName);
RaiseErrorsChanged(propertyName);
}
[XmlIgnore]
public Dictionary<string, ICollection<string>> ValidationErrors
{
get { return this._validationErrors; }
}
#endregion
}
}
答案 0 :(得分:1)
显然,基类不知道特定子类具有哪些属性,更不用说实现INDEI了。您必须编写逻辑来执行此操作。有很多方法可以实现这一目标。
对我而言,我将基本类添加一个抽象方法
abstract class ValidableBase
{
// snip
protected abstract IEnumerable<ValidableBase> GetValidableProperties();
// snip
然后更改HasErrors以递归方式调用HasErrors上述调用的结果
public bool HasErrors
{
get { return _validationErrors.Count > 0 ||
GetValidableProperties().Any(x => x.HasErrors); }
}
GetValidableProperties的示例实现可能是
protected override IEnumerable<ValidableBase> GetValidableProperties()
{
yield return SomeProperty; // a Validable property
yield return SomeOtherProperty; // this too
foreach(var prop in SomeCollectionProperty) // collection of Validable
yield return prop;
}
最后,我将Validable重命名为Validatable,这是正确的(英语)拼写。如果我是西班牙语或法语,我可能会跳过最后一步。