从UserControl获取绑定列表

问题描述:

我想编写一个通用测试,可以在没有WPF应用程序且没有TraceLogger(侦听器)的情况下运行该测试。从UserControl获取绑定列表

通用测试是suppost来比较接口与用户控件的绑定,以查看是否有缺少或太多的绑定。

IVM为视图模型 V时的接口类型是一个视图

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

我可以在某些条件下使用类似于下面的代码来获取我绑定的名称列表。 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并提供所有绑定名称的代码替换它。我看不到我将如何从用户控件获取所有绑定。我需要某种起点。

因此,本质上我寻找一个实现,提供绑定或完整绑定路径的属性名称。有没有办法从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; 
    } 
+0

您将需要遍历UserControl的所有子元素并获取每个依赖项属性的绑定表达式。这样的事情:https://*.com/questions/3586870/retrieve-all-data-bindings-from-wpf-window – mm8

+0

@ mm8我试过这个解决方案,但没有找到孩子。既不使用LogicalTreeHelper也不使用VisualTreeHelper。我认为它可能连接到WPF不运行。我的上下文是一个nunit应用程序。 – Johannes

方法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; 
    }