Search code examples
.netwinformspropertygrid

How do I control the order of ExpandableObject properties in the winforms property grid?


I have classes like:

[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class Inner
{
   public string Before{get;set}
   public string After(get;set}
}

public class Outer
{
    public Inner Inner {get;set}
}

myPropertygrid.SelectedObject = new Outer();

I wish the properties of “inner” to be displayed as “Before”, “After”, the property grid seems to put them in alphabetically order and hence display them as “After”, “Before”


Solution

  • I do not like this solution but it seems to work:

    Create a sub class of “PropertyDescriptorCollection” with all “Sort” methods override just to return “this”. So whenever the property grid calls sort to change the order of the properties, nothing happens.

    Create a subclass of “ExpandableObjectConverter” that have the “GetProperties” method overridden to return an instance of “NoneSortingPropertyDescriptorCollection” with the properties in the correct order.

    Use the [TypeConverterAttribute(typeof(MyExpandableObjectConverter))] to get your subclass of ExpandableObjectConverter used.

    public class NoneSortingPropertyDescriptorCollection : PropertyDescriptorCollection
    {
        public NoneSortingPropertyDescriptorCollection(PropertyDescriptor[] propertyDescriptors)
            : base(propertyDescriptors)
        {
        }
    
        public override PropertyDescriptorCollection Sort()
        {
            return this;
        }
        public override PropertyDescriptorCollection Sort(string[] names)
        {
            return this;
        }
    
        public override PropertyDescriptorCollection Sort(string[] names, System.Collections.IComparer comparer)
        {
            return this;
        }
        public override PropertyDescriptorCollection Sort(System.Collections.IComparer comparer)
        {
            return this;
        }
    }
    
    public class MyExpandableObjectConverter : ExpandableObjectConverter
    {
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            PropertyDescriptorCollection d = base.GetProperties(context, value, attributes);
    
            List<PropertyDescriptor> props = new List<PropertyDescriptor>();
            props.Add(d.Find("Before", false));
            props.Add(d.Find("After", false));
    
            NoneSortingPropertyDescriptorCollection m = new NoneSortingPropertyDescriptorCollection(props.ToArray());
            return m;
        }
    }
    
    [TypeConverterAttribute(typeof(MyExpandableObjectConverter))]      
    public class Inner      
    {         
       public string Before{get;set}        
       public string After(get;set}      
    }