Meilleures pratiques relatives aux règles de liaison et de validation de données WPF

101

J'ai une application WPF très simple dans laquelle j'utilise la liaison de données pour permettre l'édition de certains objets CLR personnalisés. Je souhaite maintenant mettre une validation d'entrée lorsque l'utilisateur clique sur Enregistrer. Cependant, tous les livres WPF que j'ai lus ne consacrent pas vraiment d'espace à ce problème. Je vois que vous pouvez créer des ValidationRules personnalisées, mais je me demande si cela serait excessif pour mes besoins.

Ma question est donc la suivante: existe-t-il un bon exemple d'application ou d'article quelque part qui illustre les meilleures pratiques pour valider les entrées utilisateur dans WPF?

Mark Heath
la source

Réponses:

83

Je pense que la nouvelle méthode préférée pourrait être d'utiliser IDataErrorInfo

En savoir plus ici

Rudigrobler
la source
3
J'ai également trouvé le framework Cinch ( cinch.codeplex.com ), qui comprend une démo de validation des meilleures pratiques dans WPF + MVVM, et utilise IDataErrorInfo
Mark Heath
3
Dans .NET 4.5, vous pouvez utiliser INotifyErrorInfo qui vous permet de renvoyer des objets au lieu de simplement des chaînes.
Peter
24

À partir de la documentation des modèles et pratiques de MS :

Validation des données et rapport d'erreurs

Votre modèle de vue ou modèle sera souvent requis pour effectuer la validation des données et pour signaler toute erreur de validation de données à la vue afin que l'utilisateur puisse agir pour les corriger.

Silverlight et WPF prennent en charge la gestion des erreurs de validation des données qui se produisent lors de la modification des propriétés individuelles liées aux contrôles dans la vue. Pour les propriétés uniques liées aux données à un contrôle, le modèle de vue ou le modèle peut signaler une erreur de validation des données dans le setter de propriétés en rejetant une valeur incorrecte entrante et en lançant une exception. Si la propriété ValidatesOnExceptions sur la liaison de données est true, le moteur de liaison de données dans WPF et Silverlight gérera l'exception et affichera un signal visuel à l'utilisateur indiquant qu'il y a une erreur de validation de données.

Cependant, le fait de lancer des exceptions avec des propriétés de cette manière doit être évité dans la mesure du possible. Une autre approche consiste à implémenter les interfaces IDataErrorInfo ou INotifyDataErrorInfo sur votre modèle de vue ou vos classes de modèle. Ces interfaces permettent à votre modèle de vue ou modèle d'effectuer la validation des données pour une ou plusieurs valeurs de propriété et de renvoyer un message d'erreur à la vue afin que l'utilisateur puisse être averti de l'erreur.

La documentation explique ensuite comment implémenter IDataErrorInfo et INotifyDataErrorInfo.

Tapoter
la source
3
Je me suis inquiété au début quand j'ai vu le lancer une recommandation d'exception. heureux de voir que suivi de "jeter des exceptions avec des propriétés de cette manière devrait être évité autant que possible"
kenwarner
22
il convient également de noter que certains muppet chez microsoft ont décidé de ne pas inclure INotifyDataErrorInfo dans .net4 mais uniquement dans silverlight. c'est une douleur ..
aL3891
5
@ al3891- cela sera trié dans .NET 4.5- msdn.microsoft.com/en-us/library/…
RichardOD
@ aL3891 Existe-t-il une alternative pour l'INotifyDataErrorInfo manquant?
AgentKnopf
10

Personnellement, j'utilise des exceptions pour gérer la validation. il nécessite les étapes suivantes:

  1. dans votre expression de liaison de données, vous devez ajouter "ValidatesOnException = True"
  2. dans votre objet de données auquel vous liez, vous devez ajouter le gestionnaire DependencyPropertyChanged où vous vérifiez si la nouvelle valeur remplit vos conditions - sinon - vous restaurez l'ancienne valeur de l'objet (si vous en avez besoin) et vous lancez une exception.
  3. dans votre modèle de contrôle que vous utilisez pour afficher une valeur non valide dans le contrôle, vous pouvez accéder à la collection d'erreurs et afficher un message d'exception.

l'astuce ici, est de se lier uniquement aux objets qui dérivent de DependencyObject. une implémentation simple de INotifyPropertyChanged ne fonctionnerait pas - il y a un bogue dans le framework, qui vous empêche d'accéder à la collection d'erreurs.

Greg
la source
3

Consultez également cet article . On suppose que Microsoft a publié sa bibliothèque d'entreprise (v4.0) à partir de ses modèles et pratiques où ils couvrent le sujet de validation, mais Dieu sait pourquoi ils n'ont pas inclus la validation pour WPF, donc le billet de blog vers lequel je vous dirige explique ce que l'auteur fait pour l'adapter. J'espère que cela t'aides!

Murki
la source
2

Vous pourriez être intéressé par l' exemple d'application BookLibrary de WPF Application Framework (WAF) . Il montre comment utiliser la validation dans WPF et comment contrôler le bouton Enregistrer en cas d'erreurs de validation.

jbe
la source
0

Si votre classe affaires est directement utilisée par votre interface utilisateur, il est préférable d'utiliser IDataErrorInfo car cela rapproche la logique de leur propriétaire.

Si votre classe métier est une classe stub créée par une référence à un service WCF / XmlWeb, vous ne pouvez / ne devez pas utiliser IDataErrorInfo ni lever Exception pour une utilisation avec ExceptionValidationRule. Au lieu de cela, vous pouvez:

  • Utilisez ValidationRule personnalisé.
  • Définissez une classe partielle dans votre projet d'interface utilisateur WPF et implémente IDataErrorInfo.
Alex Pollan
la source
1
Je sais que c'est vieux, mais j'espère qu'Alex pourra répondre. C'est la conclusion à laquelle je suis venu aussi, mais le problème est que vous devez écrire une validation pour (par exemple) une propriété "Age" qui ne pourrait pas être plus grande que 100 dans la ValidationRule, puis répéter la même logique dans l'interface IDataErrorInfo , qui duplique la logique. Y a-t-il un moyen de contourner cela?
JFTxJ
Où dupliquez-vous la logique? dans une sorte de validation de serveur? Je suppose par votre commentaire que vous validez avec IDataErrorInfo dans l'interface utilisateur et que vous dupliquez la validation dans l'objet métier, n'est-ce pas? Si c'est le cas, alors il est correct de valider des deux côtés. Les objets métier ne peuvent pas faire confiance aux interfaces utilisateur et doivent effectuer leur propre validation (bien que cela semble être une duplication)
Alex Pollan
Non, la duplication de la logique de validation se trouve dans IDataErrorInfo et dans la règle de validation personnalisée ... Étant donné que la règle de validation personnalisée est le seul moyen de valider les données AVANT qu'elles ne soient réellement mises à jour en objet lié, cette validation (l'âge doit être inférieur puis 100) doit être défini dans IDataErrorInfo pour renvoyer un message "par champ", mais doit également être implémenté dans la règle de validation personnalisée. Logique?
JFTxJ