Advertisement
Wednesday, June 28, 2017

.net Tips and Tricks

New .net Books!
 
LATEST NEWS

04.11.2012
BlueVision recertifies as a Microsoft Certified Partner!

02.01.2011
Georgia Municipal Association and Sophicity choose BlueVision

01.01.2010
CRC hires us again!

02.15.2009
BlueVision helps Instawares revamp Web site and shipping solution

03.30.2005
Tips and Tricks

Make properties expandable in the Property Grid with ExpandableObjectConverter

System.ComponentModel.ExpandableObjectConverter converts objects to expandable representations. It overrides GetProperties and GetPropertiesSupported to expose properties through the GetProperties method of the System.ComponentModel.TypeDescriptor class.

The ExpandableObjectConverter is simply a marker class that the PropertyGrid uses to determine if it should expand the properties of an object. For example, assume that your job is to implement the object model of a vehicle, which can be designed on a Windows form. Also, for simplicity, assume that a vehicle has a body style whose color can be customized. The model in code would look like this:

namespaceTest
{
public class Vehicle
{
  //
  // Nested class which represents a vehicle's BodyStyle
  //
  public class BodyStyle
  {
    private Color _color = Color.Black;
    [DefaultValue(typeof(System.Drawing.Color), "Black")]
    public Color BodyColor
    {
      get
      {
        return _color;
      }
      set
      {
        _color = value;
      }
    }
  }
	
  private BodyStyle _body = new BodyStyle();
	
  public BodyStyle Body
  {
    get
    {
      return _body;
    }
  }
}
}
		

You could display the properties of a vehicle in the PropertyGrid like this:

PropertyGrid propertyGrid = new PropertyGrid();
Vehicle honda = new Vehicle();
propertyGrid.SelectedObject = honda;

		

Here is how the PropertyGrid would look using the code above:

The text shown as the value of the Body property is the full name of the property's type. Test is the namespace, while Vehicle+BodyStyle represents the type of the Body property. The + sign indicates that the BodyStyle type is nested within the Vehicle type. Because no type converter was applied to the Body property or the BodyStyle type, the default implementation of the PropertyGrid calls the property's ToString method. Because ToString was not overridden in the BodyStyle class, the Object class's ToString method returns the type name.

 

Override ToString for the PropertyGrid

To allow the PropertyGrid to display useful text without applying a type converter, you must override the ToString method of BodyStyle, as shown:

public override string ToString()
{
  string body = "V-6";
  if (_color.IsNamedColor)
  {
    body += " (" + _color.Name + ")";
  }
  return body;
}

Now, the PropertyGrid should look like this:

Notice that the text is shown correctly; however, there is still no way to customize the color, as was stated in the requirements of the vehicle. This is where ExpandableObjectConverter steps in.

 

Using the ExpandableObjectConverter class

You can apply any converter derived from TypeConverter to solve the display name problem without having to override the ToString method. However, the PropertyGrid still expects to see the ExpandableObjectConverter in the attribute collection of an object in order for it to expand child properties of that object. One way to apply this converter is to simply use the TypeConverterAttribute, as shown here:

[TypeConverter(typeof(ExpandableObjectConverter))]
public class BodyStyle
		

Doing so will now yield a PropertyGrid like this:

However, there are times when you implement custom type converters that are already applied to properties and types. It then makes sense to derive your converter from ExpandableObjectConverter. But this may sometimes be a nuissance. What if you had a hierarchy of type converters, and what if your root converter was not supposed to support expanding objects, due to some other rule. This might lead to a second root for only expandable objects. Then, any base code for one converter must also be applied to the other.

 

Conlusion

To me, it would have made more sense to have a special attribute, such as ExpandableAttribute, that was used by the PropertyGrid to determine the expandability of properties. It already takes advantage of various other attributes: BrowsableAttribute, DefaultPropertyAttribute, CategoryAttribute, and DescriptionAttribute to name a few. But for now, we must accept what is there and use ExpandableObjectConverter to make our objects expandable in the PropertyGrid.


Back to Tips and Tricks

Terms Of Use © 2000 - 2017 BLUEVISION LLC. ALL RIGHTS RESERVED. Privacy Policy