我试图使用ExpandoObject作为PropertyGrid的SelectedObject。我知道如何添加属性我想要的ExpandoObject:
public dynamic MakePropertyObject()
{
dynamic expando = new ExpandoObject();
var dictionary = expando as IDictionary<string, object>;
foreach(MyClass m in PropertiesINeedToAdd)
dictionary[m.Name] = m.Value;
return expando;
}
这段代码运行良好——调试器显示了expando
属性的名称和值。
然而,当我将MakePropertyObject()
的返回值设置为其SelectedObject
属性时,生成的属性都没有显示在PropertyGrid中。我假设(也许是错误的)这是因为ExpandoObject
的属性没有任何DisplayNameAttribute
, DescriptionAttribute
或用于控制属性如何在PropertyGrid
中显示的任何其他属性。
我已经做了一些阅读和一些谷歌搜索,我不知道是否有一种方法来装饰与自定义属性的ExpandoObject
生成的属性。有没有人知道这是如何做到的,或者有更好的方法来显示ExpandoObject
在PropertyGrid
?
解决方案:
@Stephen Cleary提供的答案是正确的,很有帮助(谢谢,Stephen)。对于其他有同样问题的人,实现ICustomTypeDescriptor
对我来说是完美的。
作为旁注,实现ICustomTypeDescriptor
的对象为自己提供属性和事件描述符,而不是为另一个对象提供。我认为描述符和被描述对象应该通过一个属性或其他东西连接起来——一个对象应该描述自己的类型对我来说似乎很混乱和多余,但这确实是PropertyGrid
使用ICustomTypeDescriptor
接口的方式。
问题实际上是反射在动态类型上并没有像预期的那样工作。
PropertyGrid
使用反射来检查对象的属性,而ExpandoObject
没有任何(静态)属性。
您可以实现ICustomTypeDescriptor
来"劫持"反射并查询ExpandoObject
的(动态)属性。本文中DynamicTypeDescriptorWrapper
的代码将是一个很好的起点。