wpf - 从 WPF 窗口中检索所有数据绑定(bind)

标签 wpf validation data-binding

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

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

最佳答案

在下面试试我的示例。我还没有完全测试这个,所以它可能有问题。此外,性能可能值得怀疑。也许其他人可以帮助加快速度。但无论如何,它似乎可以解决问题。

注意:但是,对此的一个限制是它可能无法获取 Styles 或 DataTemplates 中定义的绑定(bind)。不过我不确定。需要更多的测试。

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

  • 使用 VisualTreeHelper 遍历整个可视化树。
  • 对于可视树中的每个项目,获取所有依赖项属性。 Reference .
  • 使用 BindingOperations.GetBindingBase 获取每个属性的绑定(bind)。

  • 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);
                    }
                }
            }
    

    依赖对象助手 类(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;
            }
        }
    

    示例用法:
    List<BindingBase> bindingList = new List<BindingBase>();
    GetBindingsRecursive(this, bindingList);
    
    foreach (BindingBase b in bindingList)
    {
         Console.WriteLine(b.ToString());
    }
    

    关于wpf - 从 WPF 窗口中检索所有数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3586870/

    相关文章:

    c# - 如何在开始菜单中为 ClickOnce 应用程序创建卸载链接

    jquery - 如何从 dev.jtsage 正确启用 beforeToday DateBox 选项

    c# - 使用附加文本对 C# 中的标签进行数据绑定(bind)?

    c# - 关于如何使用 UpdateSourceTrigger=Explicit 和 MVVM 的一个很好的例子

    data-binding - Grails 是否具有将字符串绑定(bind)到单个 bean 属性的日期的内置方法?

    c# - 使用导体和事件聚合器的分层导航

    wpf - MahApps DataGrid 列标题外壳

    c# - 加载具有条件字符串格式数据绑定(bind)的 XAML 失败

    ruby-on-rails - FactoryGirl has_many 与双向存在验证的关联创建额外记录

    c# - 验证 asp.net web 应用程序中的输入后,将焦点从代码隐藏到文本框