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

时间:2022-11-27 14:26:07

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:

我试图使用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;
}

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

这段代码运行良好——调试器按预期显示expando属性的名称和值。

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.

然而,当我将MakePropertyObject()的返回值设置为其SelectedObject属性时,生成的属性中没有一个显示在PropertyGrid中。我假设(可能是错误的)这是因为ExpandoObject的属性没有任何DisplayNameAttribute、DescriptionAttribute或任何其他用于控制属性在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?

我已经做了一些阅读和搜索,我不知道是否有一种方法可以用自定义属性来修饰ExpandoObject的属性。有人知道这是如何实现的吗?或者有更好的方法在PropertyGrid中显示ExpandoObject ?

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.

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

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.

作为附加说明,实现ICustomTypeDescriptor的对象为自己提供了属性和事件描述符,而不是为另一个对象。我认为描述符和描述应该是由一个属性或某种东西连接起来的——对于我来说,一个对象应该描述它自己的类型,这让我感到困惑和多余,但这确实是propertygrid使用ICustomTypeDescriptor接口的方式。

1 个解决方案

#1


6  

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.

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

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.

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

#1


6  

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.

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

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.

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