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 theAttribute[]argument to include theCategoryAttribute. 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 PropertyDescriptorto be used, the system must find it... the resolution rules are:- for PropertyGrid, theTypeConverterprovides the properties, defaulting to the properties for an instance (below)
- for an instance:
- ICustomTypeDescriptoris checked
- otherwise it checks for a registered TypeDescriptionProviderfor the instance or type
- otherwise reflection is used
 
- for a type:
- it checks for a registered TypeDescriptionProviderfor the type
- otherwise reflection is used
 
- it checks for a registered 
- for lists:
- IListSourceis checked and resolved to a list (processing continues)
- ITypedListis checked
- otherwise, the list type is checked for a non-object indexer - i.e. public SomeType this[int index] {get;}- if such is found, then the properties for the type SomeTypeare used, as defined above
 
- if such is found, then the properties for the type 
- otherwise, if the list is not empty, the properties of the first instance (list[0]) are used, as defined above
- otherwise, metadata is not available
 
 Eric Anastas : Yep the Category override you suggested worked perfectly. I knew about using the constructor, but didn't think to use a static method to simplify the code I would have to pass as an argument to the constructor. Thanks!
- for 
 
0 comments:
Post a Comment