This article provides an example of a TypeConverter which, when displayed in a Property Grid, will allow the user to select an class type from the drop down list. When an item is selected, it creates and instance of that class type. This can be used, for example, if you had a property of type Shape, and wanted to allow the user to choose a shape to assign to that property, e.g. Circle, Rectangle, etc. The property has a type of the base class Shape, but ends up with the appropriate instance of a descendant class. In the following example, I have a abstract base class of GridStyleBorder which is a property on an object.

[Category("Appearance")]
[Browsable(true)] 
[TypeConverter(typeof(GridBorderTypeConverter))] 
[RefreshProperties(RefreshProperties.All)] 
[Description("Change the Border Style")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
public GridStyleBorder Border { get {  return _border; } set { _border = value; } }

Notice the TypeConvert is set to GridBorderTypeConverter this is a new TypeConvert descended from ExpandableObjectConverter. The code is below:

 


using System;
 using System.Collections.Generic;
 using System.Text;
 using System.ComponentModel;
 using System.Collections;
 using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Reflection;
 
 namespace SomeAssemby {
    /// <summary>

    /// Provides the type converter that displays a list of types. 

    /// When the user selects an item from the list, an instance of that type is created.

    /// Note : requires customization to work with other property types. (see comments)

    /// </summary>

 
    class GridBrushTypeConverter : ExpandableObjectConverter
    {
        // set the next array to be an array of types you wish to display in the drop down

        private static readonly Type[] TypesToDisplay = new Type[] 
            { 
                typeof(SolidBrush), 
                typeof(LinearGradientBrush) 
            };
 
        // Change the modify region to If Else tests for each type you support and return appropriate instances of the types.

        public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value.GetType() == typeof(string))
            {
                string fullClassName = (string)value;
                
                #region —- need to modify this section ———————
                // check the full classname and return a new instance of that class for each of the types you support

                if (fullClassName == typeof(LinearGradientBrush).FullName)
                    return new LinearGradientBrush(new Point(0,0), new Point(0,100),SystemColors.Control, SystemColors.ControlDark);
                else
                    return new SolidBrush(SystemColors.Control);
                #endregion
            }
            else
                return base.ConvertFrom(context, culture, value);
        }
 
        #region —- No need to change this code —————————————
        private ArrayList TypesToDisplayArray = new ArrayList(TypesToDisplay);
 
        public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return true;
        }
 
        public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(TypesToDisplayArray);
        }
 
        public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            else
                return base.CanConvertFrom(context, sourceType);
        }
 
        #endregion
 
    }
 
 }