2012-03-18 146 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, ...}