inotifydataerrorinfo获取所有验证错误

本文关键字:验证 错误 获取 inotifydataerrorinfo | 更新日期: 2023-09-27 18:23:35

目前我正在开发.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 
}

}

inotifydataerrorinfo获取所有验证错误

显然,基类不知道特定子类具有什么属性,更不用说它们是否实现了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); }
}

GetValidatableProperties的一个示例实现可能是

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;
}

最后,我将Validatable重命名为Validatable,这是正确的(英语)拼写。如果我是西班牙人或法国人,我可能会跳过最后一步。