从WPF窗口检索所有数据绑定 [英] Retrieve all Data Bindings from WPF Window
问题描述
简而言之,有没有办法从WPF窗口中检索所有数据绑定的集合?
请尝试下面的示例。我还没有完全测试这个,所以可能有问题。此外,性能可能是有问题的。也许其他人可以帮助做到更快。但无论如何,它似乎是做的伎俩。
注意:对此的限制是,它可能无法选择Styles或DataTemplates中定义的绑定。我不确定。需要更多的测试。
无论如何,解决方案基本上有三个部分:
- 使用VisualTreeHelper来遍历整个视觉树。
- 对于可视树中的每个项目,获取所有依赖属性。 参考。
- 使用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 class:
public static class DependencyObjectHelper
{
public static List&BindingBase> GetBindingObjects(Object element)
{
列表< BindingBase> bindings = new List< BindingBase>();
列表< DependencyProperty> dpList = new List< DependencyProperty>();
dpList.AddRange(GetDependencyProperties(element));
dpList.AddRange(GetAttachedProperties(element));
foreach(DependencyProperty dp in dpList)
{
BindingBase b = BindingOperations.GetBindingBase(元素为DependencyObject,dp);
if(b!= null)
{
bindings.Add(b);
}
}
返回绑定;
}
public static List< DependencyProperty> GetDependencyProperties(Object element)
{
列表< 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);
}
}
}
返回属性;
}
public static List< DependencyProperty> GetAttachedProperties(Object element)
{
列表< 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;
}
}
样本用法:
列表< BindingBase> bindingList = new List< BindingBase>();
GetBindingsRecursive(this,bindingList);
foreach(bindingList中的BindingBase b)
{
Console.WriteLine(b.ToString());
}
I have a WPF form which has many controls on it. Many (but not all) of these controls are databound to an underlying object. At certain times, such as when the Save button is pressed, I need to check all the validation rules of my controls. Is there a way to do this programatically, WITHOUT hard-coding a list of the controls to be validated? I want this to continue to work after another developer adds another control and another binding, without having to update some list of bindings to be refreshed.
In a nutshell, is there any way to retrieve the collection of all data bindings from a WPF window?
Try out my sample below. I haven't fully tested this so it may have issues. Also, performance may be questionable. Maybe others can help out to make it faster. But anyway, it seems to do the trick.
Note: A limitation to this, however, is that it may not pick up the bindings defined within Styles or DataTemplates. I'm not sure though. Needs more testing.
Anyway, the solution has three parts basically:
- Use VisualTreeHelper to walk the entire visual tree.
- For each item in the visual tree, get all dependency properties. Reference.
- Use BindingOperations.GetBindingBase to get the binding for each property.
GetBindingsRecursive function:
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 class:
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;
}
}
Sample usage:
List<BindingBase> bindingList = new List<BindingBase>();
GetBindingsRecursive(this, bindingList);
foreach (BindingBase b in bindingList)
{
Console.WriteLine(b.ToString());
}
这篇关于从WPF窗口检索所有数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!