2008-12-03 68 views
4

我想在我的WPF應用程序中使用Detecting WPF Validation Errors中的解決方案執行驗證。GetLocalValueEnumerator()不返回所有屬性

public static bool IsValid(DependencyObject parent) 
{ 
    // Validate all the bindings on the parent   
    bool valid = true; 
    LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); 
    while (localValues.MoveNext()) 
    { 
     LocalValueEntry entry = localValues.Current; 
     if (BindingOperations.IsDataBound(parent, entry.Property)) 
     { 
      Binding binding = BindingOperations.GetBinding(parent, entry.Property); 
      foreach (ValidationRule rule in binding.ValidationRules) 
      { 
       ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null); 
       if (!result.IsValid) 
       { 
        BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property); 
        System.Windows.Controls.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; 
} 

我遇到的問題是,當我單步執行TextBox的代碼時,我沒有得到Text屬性。我得到的唯一屬性是「PageHeight」,「Instance」和「UndoManagerInstance」。因此,我無法驗證TextBox上綁定的規則。

有沒有人有任何想法,爲什麼我不會得到正確的屬性?有沒有另一種方法來強制WPF中的控件有效?我一直無法找到任何有此問題的人。

更新: 我想驗證的TextBoxes是在一個DataTemplate中。我發現,如果我複製其中一個TextBox並將其直接放置在窗口中,我就能夠獲取數據。使用Woodstock,我發現模板中的TextBoxes的數據源是「ParentTemplate」,但是它是模板外TextBox的「Local」。

所以,現在的問題是,我怎樣才能得到控件的DependencyProperties一個DataTemplate?

回答

4

這是兩年多了,但最近我用同樣的方法掙扎着同樣的問題。

我對這個問題的解決方案是使用反射而不是使用GetLocalValueEnumerator對DataTemplates進行corectlly工作的所有DependencyProperties對象。

代碼:

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; 
    } 

此代碼只適用於由對象所擁有的屬性來擴展它的附加屬性,你可以使用此代碼:

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; 
    }