2012-03-18 53 views
2

我正在創建類似於VS或Blend功能之一的東西,當選擇多個對象時,屬性網格顯示所有對象共享的任何屬性的值,並且不顯示任何內容對於不同對象之間的屬性。使用DynamicObject來模擬DependencyProperties

我已經成功地實現這一行爲使用動態對象CLR屬性:

  • _knownProperties只是先前已要求其屬性列表
  • _collection是一個IEnumerable實例
public override bool TryGetMember(GetMemberBinder binder, out object result) { 
    Debug.WriteLine("Getting " + binder.Name + "..."); 

    if (!_knownProperties.Contains(binder.Name)) 
     _knownProperties.Add(binder.Name); 

    IEnumerator it = _collection.GetEnumerator(); 

    if (!it.MoveNext()) { 
     result = null; 
     Debug.WriteLine("No elements in collection"); 
     return true; 
    } 

    Type t = it.Current.GetType(); 
    PropertyInfo pinf = t.GetProperty(binder.Name); 
    if (pinf == null) { 
     result = null; 
     Debug.WriteLine("Property doesn't exist."); 
     return true; 
    } 
    result = pinf.GetValue(it.Current, null); 

    if (result == null) { 
     Debug.WriteLine("Null result"); 
     return true; 
    } 
    while (it.MoveNext()) 
     if (!result.Equals(it.Current.GetType().GetProperty(binder.Name).GetValue(it.Current, null))) { 
      result = null; 
      Debug.WriteLine("Null result"); 
      return true; 
     } 

    Debug.WriteLine("Result: " + result.ToString()); 
    return true; 
} 

我通過WP訪問這些屬性F綁定。 任何人都可以想到一種方法來實現這個DependencyProperties?如果我試圖綁定到對象上的附加屬性,I(根據我有源其中是空的對象不可能爲null)

  • {Binding Selection.SomeClrProperty,...}得到在屬性系統的ArgumentNullException 。工作正常(Selection是動態對象中的一個,SomeClrProperty是集合的每一個元素上的屬性
  • {Binding Selection.(SomeClass.SomeAttachedProperty),...}火災中的錯誤屬性系統

除外:

System.ArgumentNullException was unhandled 
Message=Key cannot be null. 
Parameter name: key 
Source=System 
ParamName=key 
StackTrace: 
    at System.Collections.Specialized.HybridDictionary.get_Item(Object key) 
    at System.ComponentModel.PropertyChangedEventManager.PrivateAddListener(INotifyPropertyChanged source, IWeakEventListener listener, String propertyName) 
    at System.ComponentModel.PropertyChangedEventManager.AddListener(INotifyPropertyChanged source, IWeakEventListener listener, String propertyName) 
    at MS.Internal.Data.PropertyPathWorker.ReplaceItem(Int32 k, Object newO, Object parent) 
    at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange) 
    at MS.Internal.Data.ClrBindingWorker.AttachDataItem() 
    at System.Windows.Data.BindingExpression.Activate(Object item) 
    ... 
+0

爲了澄清,你想包括您的收藏靜態和實例屬性? (「SomeClass.SomeAttachedProperty」似乎是靜態的,但我在你的GetValue調用中看到你沒有傳入null作爲源代碼 - 獲得靜態值的必要部分。) – Brannon 2012-03-21 13:32:56

+0

@Brannon,'SomeClass.SomeAttachedProperty'將會是一個靜態字段,但該屬性的值肯定會傳遞給一個實例。使用該語法時,DynamicObject中的所有函數似乎都不會被調用,它只是產生了所聲明的錯誤。我想這是由於綁定實際上並不使用DependencyObject訪問器/增變器,而是直接從屬性系統中獲取值。 – 2012-03-21 13:49:51

回答

0

使用一次性綁定,防止WPF從試圖把一個監聽器附加屬性:

{Binding Selection.(SomeClass.SomeAttachedProperty), Mode=OneTime, ...}