是否可以向ExpandoObject实例生成的成员添加属性?



我试图使用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生成的属性。有没有人知道这是如何做到的,或者有更好的方法来显示ExpandoObjectPropertyGrid ?

解决方案:

@Stephen Cleary提供的答案是正确的,很有帮助(谢谢,Stephen)。对于其他有同样问题的人,实现ICustomTypeDescriptor对我来说是完美的。

作为旁注,实现ICustomTypeDescriptor的对象为自己提供属性和事件描述符,而不是为另一个对象提供。我认为描述符和被描述对象应该通过一个属性或其他东西连接起来——一个对象应该描述自己的类型对我来说似乎很混乱和多余,但这确实是PropertyGrid使用ICustomTypeDescriptor接口的方式。

问题实际上是反射在动态类型上并没有像预期的那样工作。

PropertyGrid使用反射来检查对象的属性,而ExpandoObject没有任何(静态)属性。

您可以实现ICustomTypeDescriptor来"劫持"反射并查询ExpandoObject的(动态)属性。本文中DynamicTypeDescriptorWrapper的代码将是一个很好的起点。

最新更新