2015-11-20 3 views
0

В настоящее время я разрабатываю приложение .net 4.5 wpf MVVM с системой проверки, обработанной INotifyDataErrorInfo. В каком-то момент в заявке я должен проверить, есть ли какая-либо ошибка проверки, в настоящее время это делается так: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

Мне любопытно, почему у вас должен быть 'Dictionary для _validationErrors', когда я бы подумал, что вам просто нужно вернуть« List »ошибок. – MethodMan

ответ

0

Очевидно, что базовый класс не имеет представления о том, что свойства определенного класса ребенок, не говоря уже, если они реализуют 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); } 
} 

Пример реализации of 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, что является правильной (английской) орфографией. Если бы я был испанский или французский, я бы, вероятно, пропустил этот последний шаг.

Смежные вопросы