Search code examples
c#propertygridpropertyinfopropertydescriptor

Get the default PropertyDescriptors for a type


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);

Solution

  • 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);
        }
    }