I have a set of custom PropertyDescriptor that I want to add categories too so they display in a more organized fashion in a PropertyGrid. I want each type of PropertyDescriptor to go into a specific Category.
I've tried using TypeDescriptor.AddAttributes() to add attributes to an existing PropertyDescriptor, but the category attribute is not added.
CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
currentDescriptor = new IntrinsicPropertyDescriptor(def);
TypeDescriptor.AddAttributes(currentDescriptor, new Attribute[] { intrinsicPropertyCategory });
I've also tried using TypeDescriptor.AddAttributes() in the constructor for one of my PropertyDescriptors as shown below. But it doesn't work either.
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 });
}
I'd rather not spend the time going in to detail of why I'm doing what I'm doing. But in the example above IntrinsicPropertyDef is a class that defines a property including a Name, Display Name and Type. So propDef.Attributes includes the DisplayNameAttribute.
An IntrinsicPropertyDef can be displayed with two different custom PropertyDescriptors IntrinsicPropertyDescriptor, and InferedIntrinsicPropertyDescriptor. Every IntrinsicPropertyDescriptor should have a category attribute "Intrinsic Properties", and every InferedIntrinsicPropertyDescriptor should have a category attribute "Inferred Intrinsic Properties".
I believe you can just override the Category
:
public override string Category { get {return "Foo";}}
For other scenarios; in general with a custom PropertyDescriptor
, you specify attributes in the constructor. You'll need to expand the Attribute[]
argument to include the CategoryAttribute
. If you need to do any processing, you can use a static method - untested:
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"))
{...}
Also - note that for a PropertyDescriptor
to be used, the system must find it... the resolution rules are:
PropertyGrid
, the TypeConverter
provides the properties, defaulting to the properties for an instance (below)ICustomTypeDescriptor
is checkedTypeDescriptionProvider
for the instance or typeTypeDescriptionProvider
for the typeIListSource
is checked and resolved to a list (processing continues)ITypedList
is checkedpublic SomeType this[int index] {get;}
SomeType
are used, as defined abovelist[0]
) are used, as defined above