Каков порядок выполнения в установщиках свойств при использовании IDataErrorInfo? - PullRequest
0 голосов
/ 16 апреля 2010

Ситуация: Много раз с WPF мы используем INotifyPropertyChanged и IDataErrorInfo для включения привязки и проверки на наших объектах данных. У меня есть много свойств, которые выглядят так:

public SomeObject SomeData
{
    get { return _SomeData; }
    set { _SomeData = value; OnPropertyChanged("SomeData"); }
}

Конечно, у меня есть соответствующий переопределенный IDataErrorInfo.this[] в моем классе, чтобы сделать проверку.

Вопрос: В каком случае выполняется код проверки? Когда устанавливается свойство? Когда выполняется установочный код? Что если проверка не пройдена?

Например:

  1. Пользователь вводит новые данные.
  2. Привязка записывает данные в свойство.
  3. Свойство set метод выполняется.
  4. Обязательные проверки this[] для проверки.
  5. Если данные недействительны, привязка устанавливает свойство обратно к старому значению.
  6. Свойство set метод выполняется снова.

Это важно, если вы добавляете «ловушки» в метод set, например:

public string PathToFile
{
    get { return _PathToFile; }
    set
    {
        if (_PathToFile != value &&      // prevent unnecessary actions
            OnPathToFileChanging(value)) // allow subclasses to do something or stop the setter
        {
            _PathToFile = value;
            OnPathToFileChanged();  // allow subclasses to do something afterwards
            OnPropertyChanged("PathToFile");
        }
    }
}

1 Ответ

1 голос
/ 16 апреля 2010

Если вы хотите детально контролировать время проверки, вы можете иметь его:

private Dictionary<string, string> Errors = new Dictionary<string, string>();

private object _MyProperty;

public object MyProperty
{
   get { return _MyProperty; }
   set
   {
      Errors["MyProperty"] = null;
      if (value == _MyProperty)
      {
         return;
      }
      ValidateMyProperty(value);  // may set Errors["MyProperty"]
      if (Errors["MyProperty"] == null)
      {
         _MyProperty = value;
         OnPropertyChanged("MyProperty");
      }
   }
}

public string this[string propertyName]
{
   return Errors[propertyName];
}

Независимо от того, когда запрашивается информация об ошибке данных и кто ее запрашивает, он всегда возвращает статус проверки свойства с момента последней попытки установить свойство.

Обратите внимание, что если вы работаете с ним, вы можете инкапсулировать логику следующим образом:

public object MyProperty
{
   set { _MyProperty = Validate("MyProperty", value, _MyProperty); }
}

private Dictionary<string, Func<object, string>> ValidationFunctions;

private object Validate(string propertyName, object value, object field)
{
   Errors[propertyName] = null;
   if (value == field)
   {
      return;
   }
   if (!ValidationFunctions.ContainsKey(propertyName))
   {
      return value;
   }
   Errors[propertyName] = ValidationFunctions[propertyName](value);
   return (Errors[propertyName] == null) 
      ? value 
      : field;
   }
}
...