2017-08-10 47 views
0

我想編寫一個通用測試,可以在沒有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://stackoverflow.com/questions/3586870/retrieve-all-data-bindings-from-wpf-window – mm8

+0

@ mm8我試過這個解決方案,但沒有找到孩子。既不使用LogicalTreeHelper也不使用VisualTreeHelper。我認爲它可能連接到WPF不運行。我的上下文是一個nunit應用程序。 – Johannes

回答

0

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