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

发布于 2024-11-03 04:55:09 字数 1275 浏览 6 评论 0原文

我正在尝试使用 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 的生成属性。有谁知道如何做到这一点,或者有更好的方法在 PropertyGrid 中显示 ExpandoObject 吗?

解决方案:

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

附带说明一下,实现 ICustomTypeDescriptor 的对象为其自身提供属性和事件描述符,而不是为另一个对象。我认为描述符和描述的内容一开始应该是通过属性或其他东西链接起来的——对象应该描述它自己的类型,这对我来说似乎令人困惑和多余,但这确实是 PropertyGrid 的使用方式ICustomTypeDescriptor 接口。

I'm trying to use an ExpandoObject as the SelectedObject of a PropertyGrid. I know how to add the properties I want to the 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;
}

This code's working fine- the debugger shows the names and values of expando's properties as expected.

However, none of the generated properties is showing up in the PropertyGrid when I set the return value of MakePropertyObject() to its SelectedObject property. I assume (perhaps falsely) that this is because the ExpandoObject's properties don't have any DisplayNameAttribute, DescriptionAttribute, or any of the other attributes used to control how properties are displayed in a PropertyGrid.

I've done some reading and some Googling, and I can't figure out if there's a way to decorate the generated properties of an ExpandoObject with custom attributes. Does anyone know how this can be done, or of a better way to show an ExpandoObject in a PropertyGrid?

SOLUTION:

The answer provided by @Stephen Cleary was correct and helpful (thanks, Stephen). For others with the same problem, implementing ICustomTypeDescriptor worked perfectly for me.

As a side note, the object that implements ICustomTypeDescriptor provides the property and event descriptors for itself, not for another object. I thought the descriptor and the described were supposed to be linked by an attribute or something at first- it seemed confusing and redundant to me that an object should describe its own type, but that's indeed how PropertyGrids use the ICustomTypeDescriptor interface.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柒夜笙歌凉 2024-11-10 04:55:09

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

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

您可以实现 ICustomTypeDescriptor “劫持”反射并查询 ExpandoObject 的(动态)属性。 这篇博文将是一个很好的起点。

The problem is actually that reflection doesn't work as expected on dynamic types.

PropertyGrid uses reflection to examine its object's properties, and ExpandoObject doesn't have any (static) properties.

You can implement ICustomTypeDescriptor to "hijack" the reflection and query the (dynamic) properties of the ExpandoObject. The code for DynamicTypeDescriptorWrapper in this blog post would be a good starting point.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文