代码之家  ›  专栏  ›  技术社区  ›  Johannes

从UserControl获取绑定列表

  •  0
  • Johannes  · 技术社区  · 7 年前

    我想编写一个通用测试,可以在没有WPF应用程序和TraceLogger(监听器)的情况下运行。

    ivm是viewmodel的一种接口类型

    v应该与ivm结合。

            var names_binding = listener.bindNames.Distinct(); //this is what i want to get rid of.
            var names_interface = ivm.GetProperties().Select(prop => prop.Name).Distinct();
            var tooMany = names_interface.Except(names_binding);
            var tooFew = names_binding.Except(names_interface);
    

    我可以使用下面类似的代码获得在特定条件下绑定到的名称列表。其中a listener

            object obj = new object();
            T_V view = new T_V();
            view.DataContext = obj; // empty object - all binding will fail
            DoEvents(); // Do Events pumps WPF so binding happens
    

    我想用检查usercontrol并交付所有绑定名称的代码来替换它。我不知道如何从用户控件获取所有绑定。我需要某种起点。

        public IEnumerable<string> GetBindingPaths<T_V>() where T_V : UserControl, new()
        {
            var ret = Enumerable.Empty<string>();
            T_V view = new T_V();
            //// view.GetBindingExpression ???
            //// view.GetLocalValueEnumerator ???
            return ret;
        }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Johannes    7 年前

    方法 GetLocalValueEnumerator 这就是我想要的。我只是不知道如何立即使用它。下面是一个示例实现:

        private IEnumerable<string> GetBindingPropertyNames(DependencyObject target)
        {
            return from path in GetBindingPaths(target) select path.Split('.').First();
        }
    
        private IEnumerable<string> GetBindingPaths(DependencyObject target)
        {
            var ret = new List<string>();
            LocalValueEnumerator lve = target.GetLocalValueEnumerator();
    
            while (lve.MoveNext())
            {
                LocalValueEntry entry = lve.Current;
                if (entry.Value is DependencyObject)
                {
                    ret.AddRange(GetBindingPaths(entry.Value as DependencyObject));
                }
    
                if (BindingOperations.IsDataBound(target, entry.Property))
                {
                    Binding binding = (entry.Value as BindingExpression).ParentBinding;
                    ret.Add(binding.Path.Path);
                }
            }
            return ret;
        }