【问题标题】:Add a category attribute to a PropertyDescriptor将类别属性添加到 PropertyDescriptor
【发布时间】:2009-05-05 19:04:51
【问题描述】:

我有一组自定义 PropertyDescriptor,我也想添加类别,以便它们在 PropertyGrid 中以更有条理的方式显示。我希望每种类型的 PropertyDescriptor 进入一个特定的类别。

我尝试使用 TypeDescriptor.AddAttributes() 将属性添加到现有的 PropertyDescriptor,但没有添加类别属性。

CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
currentDescriptor = new IntrinsicPropertyDescriptor(def);
TypeDescriptor.AddAttributes(currentDescriptor, new Attribute[] { intrinsicPropertyCategory });

我还尝试在构造函数中为我的一个 PropertyDescriptor 使用 TypeDescriptor.AddAttributes(),如下所示。但它也不起作用。

public IntrinsicPropertyDescriptor(IntrinsicPropertyDef propDef): base(propDef.Key, propDef.Attributes)
{
this._type = propDef.Type;
this._key = propDef.Key;
this._readOnly = propDef.ReadOnly;

CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
TypeDescriptor.AddAttributes(this, new Attribute[] { intrinsicPropertyCategory });
}

我宁愿不花时间详细说明我为什么要做我正在做的事情。但在上面的示例中,IntrinsicPropertyDef 是一个定义属性的类,包括名称、显示名称和类型。所以 propDef.Attributes 包括 DisplayNameAttribute。

可以使用两个不同的自定义 PropertyDescriptor IntrinsicPropertyDescriptor 和 InferedIntrinsicPropertyDescriptor 来显示 IntrinsicPropertyDef。每个 IntrinsicPropertyDescriptor 都应该有一个类别属性“Intrinsic Properties”,每个 InferedIntrinsicPropertyDescriptor 都应该有一个类别属性“Inferred Intrinsic Properties”。

【问题讨论】:

    标签: c# typedescriptor propertydescriptor


    【解决方案1】:

    相信你可以覆盖Category

    public override string Category { get {return "Foo";}}
    

    对于其他场景;通常使用自定义PropertyDescriptor,您可以在构造函数中指定属性。您需要扩展 Attribute[] 参数以包含 CategoryAttribute。如果需要做任何处理,可以使用静态方法——未经测试:

    static Attribute[] AddCategory(Attribute[] attributes, string category) {
        Array.Resize(ref attributes, attributes.Length + 1);
        attributes[attributes.Length - 1] = new CategoryAttribute(category);
        return attributes;
    }
    public IntrinsicPropertyDescriptor(IntrinsicPropertyDef propDef)
         : base(propDef.Key, AddCategory(propDef.Attributes, "Foo"))
    {...}
    

    另外 - 请注意,要使用 PropertyDescriptor,系统必须找到它...解析规则是:

    • 对于PropertyGridTypeConverter 提供属性,默认为实例的属性(如下)
    • 例如:
      • ICustomTypeDescriptor 被选中
      • 否则它会检查实例或类型的注册TypeDescriptionProvider
      • 否则使用反射
    • 对于一个类型:
      • 它检查注册的TypeDescriptionProvider 类型
      • 否则使用反射
    • 对于列表:
      • IListSource 被检查并解析为一个列表(处理继续)
      • ITypedList 被选中
      • 否则,将检查列表类型以查找非对象索引器 - 即public SomeType this[int index] {get;}
        • 如果找到,则使用 SomeType 类型的属性,如上所述
      • 否则,如果列表不为空,则使用第一个实例 (list[0]) 的属性,如上所述
      • 否则,元数据不可用

    【讨论】:

    • 是的,您建议的类别覆盖效果很好。我知道使用构造函数,但没有想到使用静态方法来简化我必须作为参数传递给构造函数的代码。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    相关资源
    最近更新 更多