2010-08-27 53 views
2

我有一個WPF窗體,它有很多控件。這些控件中的很多(但不是全部)都是將數據綁定到底層對象。在某些時候,例如按下保存按鈕時,我需要檢查我的控件的所有驗證規則。有沒有辦法以編程方式執行此操作,硬編碼要驗證的控件列表?我希望在另一個開發人員添加另一個控件和另一個綁定後繼續工作,而不必更新要刷新的某些綁定列表。從WPF窗口檢索所有數據綁定

簡而言之,有什麼辦法從WPF窗口檢索所有數據綁定的集合嗎?

+0

問題是模糊的,所以我不能確定。但任何有類似情況的人都可能想使用['BindingGroup'](https://msdn.microsoft.com/en-us/library/system.windows.data.bindinggroup(v = vs.110))。 aspx)作爲組織相關綁定的一種方式,以便可以完成一次性驗證。 – 2015-09-15 17:48:43

回答

5

試試我下面的示例。我沒有完全測試過,所以它可能有問題。此外,表現可能有問題。也許其他人可以幫助加快速度。但無論如何,它似乎在伎倆。

注意:但是,對此的一個限制是它可能無法獲取在樣式或數據模板中定義的綁定。雖然我不確定。需要更多測試。

無論如何,解決方案有三個基本部分:

  1. 使用VisualTreeHelper遍歷整個視覺樹。
  2. 對於可視化樹中的每個項目,獲取所有依賴屬性。 Reference
  3. 使用BindingOperations.GetBindingBase獲取每個屬性的綁定。

GetBindingsRecursive功能:

void GetBindingsRecursive(DependencyObject dObj, List<BindingBase> bindingList) 
     { 
      bindingList.AddRange(DependencyObjectHelper.GetBindingObjects(dObj)); 

      int childrenCount = VisualTreeHelper.GetChildrenCount(dObj); 
      if (childrenCount > 0) 
      { 
       for (int i = 0; i < childrenCount; i++) 
       { 
        DependencyObject child = VisualTreeHelper.GetChild(dObj, i); 
        GetBindingsRecursive(child, bindingList); 
       } 
      } 
     } 

DependencyObjectHelper類:

public static class DependencyObjectHelper 
    { 
     public static List<BindingBase> GetBindingObjects(Object element) 
     { 
      List<BindingBase> bindings = new List<BindingBase>(); 
      List<DependencyProperty> dpList = new List<DependencyProperty>(); 
      dpList.AddRange(GetDependencyProperties(element)); 
      dpList.AddRange(GetAttachedProperties(element)); 

      foreach (DependencyProperty dp in dpList) 
      { 
       BindingBase b = BindingOperations.GetBindingBase(element as DependencyObject, dp); 
       if (b != null) 
       { 
        bindings.Add(b); 
       } 
      } 

      return bindings; 
     } 

     public static List<DependencyProperty> GetDependencyProperties(Object element) 
     { 
      List<DependencyProperty> properties = new List<DependencyProperty>(); 
      MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(element); 
      if (markupObject != null) 
      { 
       foreach (MarkupProperty mp in markupObject.Properties) 
       { 
        if (mp.DependencyProperty != null) 
        { 
         properties.Add(mp.DependencyProperty); 
        } 
       } 
      } 

      return properties; 
     } 

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

      return attachedProperties; 
     } 
    } 

示例用法:

List<BindingBase> bindingList = new List<BindingBase>(); 
GetBindingsRecursive(this, bindingList); 

foreach (BindingBase b in bindingList) 
{ 
    Console.WriteLine(b.ToString()); 
} 
+0

爲什麼VisualTreeHelper而不是LogicalTreeHelper?任何具體原因? – 2015-08-07 12:05:03

+0

在我的情況下,我需要使用LogicalTreeHelper或不是我樹中的所有UIElements都被找到。我對Visual/LogicalTreeHelper沒有足夠的理解來解釋這一點,但只是想讓我知道。 – 2016-06-16 20:31:55

4

Ť這裏是.NET 4.5及以上版本的更好的解決方案:

foreach (BindingExpressionBase be in BindingOperations.GetSourceUpdatingBindings(element)) 
{ 
    be.UpdateSource(); 
} 
+1

這並不完全一樣,因爲它只返回處於特定狀態的綁定。你不能使用它來查找所有綁定。 – 2015-08-07 12:02:00