Get the default PropertyDescriptors for a type

Eric Anastas picture Eric Anastas · Apr 9, 2009 · Viewed 8.4k times · Source

I'm customizing how an object type is displayed in a PropertyGrid by implementing ICustomTypeDescriptor. I'm allowing the user to create their own custom properties that are stored in a single dictionary of keys and values. I'm able to create all the PropertyDescriptors for these values and view them in the property grid. However, I also want to show all the default properties that otherwise would have shown if the PropertyGrid was populated through reflection rather than my override ICustomTypeDescriptor.GetProperties method.

Now I know how to get the type of the object, and then GetProperties(), but this returns an array of PropertyInfo not ProperyDescriptor. So how can I convert the PropertyInfo object of the type into PropertyDescriptor objects to include into my collection with the custom PropertyDescriptors?

//gets the local intrinsic properties of the object
Type thisType = this.GetType();
PropertyInfo[] thisProps = thisType.GetProperties();

//this line obviously doesn't work because the propertydescriptor 
//collection needs an array of PropertyDescriptors not PropertyInfo
PropertyDescriptorCollection propCOl = 
    new PropertyDescriptorCollection(thisProps);

Answer

Marc Gravell picture Marc Gravell · Apr 9, 2009
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(thisType);

As an aside: this won't include your ICustomTypeDescriptor customisations, but it will include any customisations made via TypeDescriptionProvider.

(edit) As a second aside - you can also tweak PropertyGrid by providing a TypeConverter - much simpler than either ICustomTypeDescriptor or TypeDescriptionProvider - for example:

[TypeConverter(typeof(FooConverter))]
class Foo { }

class FooConverter : ExpandableObjectConverter
{
    public override PropertyDescriptorCollection GetProperties(
       ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
        // your code here, perhaps using base.GetPoperties(
        //    context, value, attributes);
    }
}