将类别属性添加到PropertyDescriptor

时间:2009-05-05 19:04:51

标签: c# typedescriptor propertydescriptor

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

我尝试使用TypeDescriptor.AddAttributes()向现有PropertyDescriptor添加属性,但未添加category属性。

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

我也尝试在我的一个PropertyDescriptors的构造函数中使用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是一个定义属性的类,包括Name,Display Name和Type。所以propDef.Attributes包含DisplayNameAttribute。

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

1 个答案:

答案 0 :(得分:4)

相信你可以覆盖Category

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

对于其他场景;通常使用自定义PropertyDescriptor,您可以在构造函数中指定属性。您需要展开{​​{1}}参数以包含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")) {...} ,系统必须找到它...解析规则是:

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