从 WPF 窗口检索所有数据绑定 [英] Retrieve all Data Bindings from WPF Window

查看:19
本文介绍了从 WPF 窗口检索所有数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WPF 表单,上面有很多控件.许多(但不是全部)这些控件都数据绑定到底层对象.在某些时候,例如按下 Save 按钮时,我需要检查我的控件的所有验证规则.有没有办法以编程方式执行此操作,无需硬编码要验证的控件列表?我希望在另一个开发人员添加另一个控件和另一个绑定后继续工作,而不必更新一些要刷新的绑定列表.

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.

简而言之,有没有办法从 WPF 窗口中检索所有数据绑定的集合?

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.

注意:但是,对此的限制是它可能无法获取在样式或数据模板中定义的绑定.我不确定.需要更多测试.

无论如何,解决方案基本上分为三个部分:

Anyway, the solution has three parts basically:

  1. 使用 VisualTreeHelper 遍历整个可视化树.
  2. 对于可视化树中的每个项目,获取所有依赖项属性.参考.
  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());
}

这篇关于从 WPF 窗口检索所有数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆