1

我有一组自定义的 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”。

4

1 回答 1

4

相信你可以覆盖Category

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

对于其他场景;通常使用 custom 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要使用 a ,系统必须找到它......解析规则是:

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