Когда вызывается INotifyDataErrorInfo.GetErrors с нулевым vs String.empty?

На странице msdn для InotifyDataErrorInfo.GetErrors говорится, что метод GetErrors вызывается с параметром, который может быть:

  • Имя свойства, которое мы хотим получить информацию об ошибке для
  • Null
  • String.Empty

Документация не указывает, когда этот метод вызывается с нулевым vs String.Empty. Я видел оба случая в своем приложении, и мне нужно понять, когда я могу ожидать того или другого.

Уточнение: Я не спрашиваю о том, как я должен реализовать метод GetErrors (я просто тестирую как нулевые, так и пустые). Вопрос заключается в том, чтобы понять, почему инфраструктура WPF пытается вызвать этот метод, иногда с нулевым, а иногда и с пустой строкой (я столкнулся с обоими случаями в своем приложении). Если целью является запрос ошибок, которые не привязаны к определенному свойству, зачем использовать два разных значения для вызова, когда достаточно одного?

Ответ 1

Вы должны ожидать как null, так и string.Empty, когда вызывающий объект хочет знать не ошибку для определенного параметра, а ошибки для всех параметров объекта. Поэтому вы не должны делать разницу между null и string.Empty.

Итак, что-то в этом роде:

if(string.IsNullOrEmpty(propertyName))
{
    // return all errors
}
else
{
    // return the error for the parameter 'propertyName'
}

Ответ 2

WPF вызывает InotifyDataErrorInfo.GetErrors(null/string.Empty), чтобы получить ошибки "всей модели представления". Все элементы управления, которые имеют контекст данных или привязку к модели представления с "ошибками всей модели модели", будут отображаться с шаблоном ошибок. Например, у вас есть учетная запись модели Credentials с двумя свойствами: UserName, Password. Вы можете реализовать что-то вроде этого:

IEnumerable InotifyDataErrorInfo.GetErrors(string propertyName)
    {
        if (UserNames.Length == 0)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                return "Some credentials component is wrong.";
            }
            else if (propertyName == "UserNames")
            {
                return "User name is required field.";
           }
        }
    }

Однако в большинстве случаев вы можете вернуть null, когда string.IsNullOrEmpty(propertyName).

Ответ 3

Когда вызывается INotifyDataErrorInfo.GetErrors с нулевым vs String.empty?

Если вы хотите проверить одно свойство, вы вызываете

RaiseEvent ErrorsChanged(Me, New DataErrorsChangedEventArgs("PropertyName"))

из сеттера этого свойства.

Если вы хотите проверить всю сущность, вы вызываете

RaiseEvent ErrorsChanged(Me, New DataErrorsChangedEventArgs(String.Empty))

из какого-то "центрального" места, например, "Сохранить кнопку" или "Закрытие окна".

Ответ 4

Вы получаете нулевой аргумент, когда привязка ссылается на отсутствие свойства, как с путем по умолчанию:

DataContext="{Binding ValidatesOnNotifyDataErrors=True}"
DataContext="{Binding Path=., ValidatesOnNotifyDataErrors=True}"

Этого можно избежать, указав фактическое свойство в Path. Конечно, это может быть свойство в модели представления, включая то, которое просто возвращает "this".

Tag="{Binding Path=DataContext, RelativeSource={RelativeSource Self}, ValidatesOnNotifyDataErrors=True}"

Что касается string.Emtpy, это явно в структуре для внутреннего метода BindingExpression.UpdateNotifyDataErrors:

List<object> propertyErrors = GetDataErrors(indei, propertyName);
List<object> valueErrors = GetDataErrors(dataErrorValue, String.Empty);
List<object> errors = MergeErrors(propertyErrors, valueErrors);

Предупреждение: обратите внимание на вышеописанную операцию агрегирования, поэтому, если вы используете string.IsNullOrEmpty для проверки того, что платформа запрашивает ошибки на уровне сущности, и возвращают те же ошибки независимо от "null" против string.Emtpy, вы можете получить дубликаты сообщений. в пользовательском интерфейсе (один для "ноль" и другой для string.Empty). По крайней мере, в сегодняшних выпусках .NET Framework.