2008-12-03 14 views
4

J'essaie d'effectuer une validation dans mon application WPF en utilisant la solution dans Detecting WPF Validation Errors. Le problème que je rencontre est que lorsque je parcours le code d'un TextBox, je ne reçois pas la propriété Text. Les seules propriétés que je reçois sont "PageHeight", "Instance" et "UndoManagerInstance". Par conséquent, je ne peux pas valider les règles pour la liaison sur le TextBox.GetLocalValueEnumerator() Ne pas retourner toutes les propriétés

Quelqu'un at-il une idée de pourquoi je ne serais pas obtenir les bonnes propriétés? Existe-t-il un autre moyen de forcer validaton sur les contrôles dans WPF? Je n'ai pas pu trouver quelqu'un d'autre qui a eu ce problème.

Mise à jour: Les zones de texte que j'essaie de valider se trouvent dans un DataTemplate. J'ai trouvé que si je copie l'un des TextBoxes et le place directement dans la fenêtre, je peux obtenir les données. En utilisant Woodstock, j'ai vu que la source de données pour les TextBoxes dans le template est "ParentTemplate", mais c'est "Local" pour le TextBox en dehors du template.

Donc, la question est maintenant, comment puis-je obtenir le DependencyProperties pour les contrôles un DataTemplate?

Répondre

4

Cela fait plus de deux ans mais récemment je luttais avec le même problème en utilisant la même méthode.

Ma solution à ce problème consiste à obtenir toutes les DependencyProperties de l'objet en utilisant la réflexion au lieu d'utiliser GetLocalValueEnumerator qui ne fonctionne pas corectlly avec DataTemplates.

code:

public static bool IsValid(DependencyObject parent) 
    { 
     // Validate all the bindings on the parent   
     bool valid = true; 
     var infos = parent.GetType().GetFields(
         BindingFlags.Public 
         | BindingFlags.FlattenHierarchy 
         | BindingFlags.Instance 
         | BindingFlags.Static).Where(f => f.FieldType == typeof(DependencyProperty)); 
     foreach (FieldInfo field in infos) 
     { 
      var dp = (DependencyProperty)field.GetValue(null); 
      if (BindingOperations.IsDataBound(parent, dp)) 
      { 
       Binding binding = BindingOperations.GetBinding(parent, dp); 
       foreach (ValidationRule rule in binding.ValidationRules) 
       { 
        ValidationResult result = rule.Validate(parent.GetValue(dp), null); 
        if (!result.IsValid) 
        { 
         BindingExpression expression = BindingOperations.GetBindingExpression(parent, dp); 
         Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null)); 
         valid = false; 
        } 
       } 
      } 
     } 
     // Validate all the bindings on the children 
     for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(parent, i); 
      if (!IsValid(child)) 
      { 
       valid = false; 
      } 
     } 
     return valid; 
    } 

Ce code fonctionne uniquement avec des propriétés appartenant à l'objet de l'étendre pour les propriétés attachées vous pouvez utiliser ce code:

public static List<DependencyProperty> GetAttachedProperties(Object element) 
    { 
     List<DependencyProperty> attachedProperties = new List<DependencyProperty>(); 
     System.Windows.Markup.Primitives.MarkupObject markupObject = 
      System.Windows.Markup.Primitives.MarkupWriter.GetMarkupObjectFor(element); 
     if (markupObject != null) 
     { 
      foreach (System.Windows.Markup.Primitives.MarkupProperty mp in markupObject.Properties) 
      { 
       if (mp.IsAttached) 
       { 
        attachedProperties.Add(mp.DependencyProperty); 
       } 
      } 
     } 

     return attachedProperties; 
    } 
Questions connexes