我有一个WPF表单,它有很多控件.许多(但不是全部)这些控件都被数据绑定到底层对象.在某些时候,例如按下“保存”按钮时,我需要检查控件的所有验证规则.有没有办法以编程方式执行此
简而言之,有没有办法从WPF窗口检索所有数据绑定的集合?
试试下面的示例.我没有对此进行全面测试,因此可能存在问题.此外,性能可能有问题.也许其他人可以帮助他们加快速度.但无论如何,它似乎做了伎俩.注意:但是,对此的限制是它可能无法获取Styles或DataTemplates中定义的绑定.我不确定.需要更多测试.
无论如何,解决方案基本上有三个部分:
>使用VisualTreeHelper遍历整个可视树.
>对于可视化树中的每个项目,获取所有依赖项属性. Reference.
>使用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()); }