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

5

我想将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的属性没有任何DisplayNameAttributeDescriptionAttribute或其他用于控制如何在PropertyGrid中显示属性的属性。

我已经阅读了一些资料并进行了一些谷歌搜索,但我无法弄清楚是否有办法用自定义属性装饰一个ExpandoObject的生成属性。有人知道如何做到这一点吗?或者有更好的方法来展示一个ExpandoObject在一个PropertyGrid中吗?

解决方案:

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

顺便说一下,实现ICustomTypeDescriptor的对象为自己提供属性和事件描述符,而不是另一个对象。一开始我以为描述符和描述的东西应该通过某种属性之类的东西链接在一起 - 对我来说,一个对象应该描述自己的类型似乎有些混淆和多余,但这确实是PropertyGrid如何使用ICustomTypeDescriptor接口。

1个回答

8

问题实际上在于反射无法按照预期在动态类型上工作。

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接