Рекомендации по использованию правил привязки и проверки данных WPF

101

У меня очень простое приложение WPF, в котором я использую привязку данных, чтобы разрешить редактирование некоторых настраиваемых объектов CLR. Теперь я хочу добавить некоторую проверку ввода, когда пользователь нажимает кнопку «Сохранить». Однако все книги WPF, которые я прочитал, на самом деле не посвящают этому вопросу места. Я вижу, что вы можете создавать собственные ValidationRules, но мне интересно, будет ли это излишним для моих нужд.

Итак, у меня такой вопрос: есть ли где-нибудь хороший образец приложения или статьи, демонстрирующие передовой опыт проверки пользовательского ввода в WPF?

Марк Хит
источник

Ответы:

83

Я думаю, что новый предпочтительный способ - использовать IDataErrorInfo

Подробнее здесь

рудигроблер
источник
3
Я также нашел фреймворк Cinch ( cinch.codeplex.com ), который включает демонстрацию проверки передовых практик в WPF + MVVM и использует IDataErrorInfo
Марк Хит
3
В .NET 4.5 вы можете использовать INotifyErrorInfo, который позволяет вам возвращать объекты, а не просто строки.
Питер
24

Из документации MS Patterns & Practices :

Проверка данных и отчеты об ошибках

Ваша модель представления или модель часто требуется для выполнения проверки данных и для сообщения любых ошибок проверки данных представлению, чтобы пользователь мог их исправить.

Silverlight и WPF обеспечивают поддержку управления ошибками проверки данных, возникающими при изменении отдельных свойств, привязанных к элементам управления в представлении. Для отдельных свойств, привязанных к элементу управления, модель или модель представления может сигнализировать об ошибке проверки данных в установщике свойств, отклоняя входящее неверное значение и создавая исключение. Если свойство ValidatesOnExceptions привязки данных имеет значение true, механизм привязки данных в WPF и Silverlight обработает исключение и отобразит визуальный сигнал для пользователя об ошибке проверки данных.

Однако по возможности следует избегать создания исключений со свойствами таким образом. Альтернативный подход - реализовать интерфейсы IDataErrorInfo или INotifyDataErrorInfo в вашей модели представления или классах моделей. Эти интерфейсы позволяют вашей модели представления или модели выполнять проверку данных для одного или нескольких значений свойств и возвращать сообщение об ошибке в представление, чтобы пользователь мог быть уведомлен об ошибке.

В документации объясняется, как реализовать IDataErrorInfo и INotifyDataErrorInfo.

Пэт
источник
3
Сначала я забеспокоился, когда увидел рекомендацию об исключении. рад видеть, что за этим следует «по возможности избегать
создания
22
Следует также отметить, что некоторые маппеты в Microsoft решили не включать INotifyDataErrorInfo в .net4, а только в silverlight. это боль ..
aL3891
5
@ al3891- это будет отсортирован в .NET 4.5- msdn.microsoft.com/en-us/library/...
RichardOD
@ aL3891 Есть ли альтернатива отсутствующему INotifyDataErrorInfo?
AgentKnopf
10

лично я использую исключения для обработки проверки. это требует следующих шагов:

  1. в выражении привязки данных вам нужно добавить ValidatesOnException = True
  2. в вашем объекте данных, к которому вы привязываетесь, вам нужно добавить обработчик DependencyPropertyChanged, где вы проверяете, соответствует ли новое значение вашим условиям - если нет - вы восстанавливаете старое значение объекта (если вам нужно) и генерируете исключение.
  3. в шаблоне элемента управления, который вы используете для отображения недопустимого значения в элементе управления, вы можете получить доступ к сбору ошибок и отобразить сообщение об исключении.

уловка здесь заключается в том, чтобы привязать только к объектам, которые являются производными от DependencyObject. простая реализация INotifyPropertyChanged не сработает - в структуре есть ошибка, которая не позволяет вам получить доступ к коллекции ошибок.

Грег
источник
3

Также проверьте эту статью . Предположительно Microsoft выпустила свою корпоративную библиотеку (v4.0) из своих шаблонов и практик, в которых они охватывают тему проверки, но бог знает, почему они не включили проверку для WPF, поэтому сообщение в блоге, к которому я вас направляю, объясняет, что автор сделал, чтобы адаптировать его. Надеюсь это поможет!

мурки
источник
2

Возможно, вас заинтересует пример приложения BookLibrary из WPF Application Framework (WAF) . В нем показано, как использовать проверку в WPF и как управлять кнопкой «Сохранить» при наличии ошибок проверки.

jbe
источник
0

Если ваш бизнес-класс напрямую используется вашим пользовательским интерфейсом, предпочтительнее использовать IDataErrorInfo, потому что это приближает логику к их владельцу.

Если ваш бизнес-класс является классом-заглушкой, созданным ссылкой на службу WCF / XmlWeb, вы не можете / не должны использовать IDataErrorInfo или генерировать исключение для использования с ExceptionValidationRule. Вместо этого вы можете:

  • Используйте настраиваемое ValidationRule.
  • Определите частичный класс в своем проекте пользовательского интерфейса WPF и реализуйте IDataErrorInfo.
Алекс Поллан
источник
1
Я знаю, что это устарело, но надеюсь, Алекс сможет ответить. К этому же выводу я пришел, но проблема в том, что вам нужно написать некоторую проверку (например) для свойства "Age", которое не может быть больше 100 в ValidationRule, а затем повторить ту же логику в интерфейсе IDataErrorInfo. , что дублирует логику. Есть ли способ обойти это?
JFTxJ
Где продублируете логику? в какой-то валидации сервера? По вашему комментарию я предполагаю, что вы проверяете с помощью IDataErrorInfo в пользовательском интерфейсе и дублируете проверку в бизнес-объекте, не так ли? Если да, то правильность проверки с обеих сторон. Бизнес-объекты не могут доверять пользовательскому интерфейсу и должны выполнять свою собственную проверку (хотя это кажется дублированием)
Алекс Поллан
Нет, дублирование логики проверки находится в IDataErrorInfo и в настраиваемом правиле проверки ... Поскольку настраиваемое правило проверки - единственный способ проверить данные ДО того, как они будут фактически обновлены для привязанного объекта, эта проверка (возраст должен быть ниже затем 100) необходимо определить в IDataErrorInfo для возврата сообщения «для каждого поля», но также необходимо реализовать в настраиваемом правиле проверки. Имеет смысл?
JFTxJ 07