我有一個WPF窗體,它有很多控件。這些控件中的很多(但不是全部)都是將數據綁定到底層對象。在某些時候,例如按下保存按鈕時,我需要檢查我的控件的所有驗證規則。有沒有辦法以編程方式執行此操作,無硬編碼要驗證的控件列表?我希望在另一個開發人員添加另一個控件和另一個綁定後繼續工作,而不必更新要刷新的某些綁定列表。從WPF窗口檢索所有數據綁定
簡而言之,有什麼辦法從WPF窗口檢索所有數據綁定的集合嗎?
我有一個WPF窗體,它有很多控件。這些控件中的很多(但不是全部)都是將數據綁定到底層對象。在某些時候,例如按下保存按鈕時,我需要檢查我的控件的所有驗證規則。有沒有辦法以編程方式執行此操作,無硬編碼要驗證的控件列表?我希望在另一個開發人員添加另一個控件和另一個綁定後繼續工作,而不必更新要刷新的某些綁定列表。從WPF窗口檢索所有數據綁定
簡而言之,有什麼辦法從WPF窗口檢索所有數據綁定的集合嗎?
試試我下面的示例。我沒有完全測試過,所以它可能有問題。此外,表現可能有問題。也許其他人可以幫助加快速度。但無論如何,它似乎在伎倆。
注意:但是,對此的一個限制是它可能無法獲取在樣式或數據模板中定義的綁定。雖然我不確定。需要更多測試。
無論如何,解決方案有三個基本部分:
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());
}
爲什麼VisualTreeHelper而不是LogicalTreeHelper?任何具體原因? – 2015-08-07 12:05:03
在我的情況下,我需要使用LogicalTreeHelper或不是我樹中的所有UIElements都被找到。我對Visual/LogicalTreeHelper沒有足夠的理解來解釋這一點,但只是想讓我知道。 – 2016-06-16 20:31:55
Ť這裏是.NET 4.5及以上版本的更好的解決方案:
foreach (BindingExpressionBase be in BindingOperations.GetSourceUpdatingBindings(element))
{
be.UpdateSource();
}
這並不完全一樣,因爲它只返回處於特定狀態的綁定。你不能使用它來查找所有綁定。 – 2015-08-07 12:02:00
問題是模糊的,所以我不能確定。但任何有類似情況的人都可能想使用['BindingGroup'](https://msdn.microsoft.com/en-us/library/system.windows.data.bindinggroup(v = vs.110))。 aspx)作爲組織相關綁定的一種方式,以便可以完成一次性驗證。 – 2015-09-15 17:48:43