2009-03-13 8 views
6

J'ai une zone de texte dans une application WPF liée à une propriété d'une classe Linq to Entities qui implémente IDataErrorInfo. La liaison de la zone de texte a ValidatesOnExceptions = True et ValidatesOnDataErrors = True. Lorsque la zone de texte est liée à une propriété entière et que l'utilisateur entre du texte, le contour de la zone de texte s'affiche en rouge car je n'ai pas défini de style personnalisé.Liaison WPF - Comment déterminer que l'objet n'est pas valide pour empêcher l'enregistrement

Dans ma méthode Save, comment puis-je savoir que l'objet ne peut pas être enregistré car il n'est pas valide? Je préfère que l'utilisateur clique sur le bouton Enregistrer et que je puisse les prévenir d'un problème plutôt que de désactiver le bouton Enregistrer.

Cheers,

Dave

Répondre

5

Je n'ai pas trouvé un moyen facile de le faire. J'ai trouvé du code autour des traps pour recurse à travers tous les contrôles sur le formulaire et déterminer si certains d'entre eux ont des erreurs de validation. J'ai fini par la transformer en une méthode d'extension:

// Validate all dependency objects in a window 
internal static IList<ValidationError> GetErrors(this DependencyObject node) 
{ 
    // Check if dependency object was passed 
    if (node != null) 
    { 
     // Check if dependency object is valid. 
     // NOTE: Validation.GetHasError works for controls that have validation rules attached 
     bool isValid = !Validation.GetHasError(node); 
     if (!isValid) 
     { 
      // If the dependency object is invalid, and it can receive the focus, 
      // set the focus 
      if (node is IInputElement) Keyboard.Focus((IInputElement)node); 
      return Validation.GetErrors(node); 
     } 
    } 

    // If this dependency object is valid, check all child dependency objects 
    foreach (object subnode in LogicalTreeHelper.GetChildren(node)) 
    { 
     if (subnode is DependencyObject) 
     { 
      // If a child dependency object is invalid, return false immediately, 
      // otherwise keep checking 
      var errors = GetErrors((DependencyObject)subnode); 
      if (errors.Count > 0) return errors; 
     } 
    } 

    // All dependency objects are valid 
    return new ValidationError[0]; 
} 

Alors lorsque l'utilisateur clique sur le bouton Enregistrer sur un formulaire, je fais ceci:

var errors = this.GetErrors(); 
if (errors.Count > 0) 
{ 
    MessageBox.Show(errors[0].ErrorContent.ToString()); 
    return; 
} 

Il y a beaucoup plus de travail qu'il devrait être , mais en utilisant la méthode d'extension le simplifie un peu.

+0

C'est une bonne solution. Je vous remercie. – Jirapong

3

Vous pouvez définir NotifyOnValidationError à true sur vos Binding s, puis ajoutez un gestionnaire pour l'événement Error sur un élément parent. L'événement se déclenchera lorsqu'une erreur est ajoutée ou supprimée.

+0

super idée! Je posterai ma solution une fois que je l'appliquerai à mon code! –