After the last post I thought I might come up with some real world examples. Just to give you an idea how usefull type converters can be at design time.
There are various situations where a string property should be set to a value from a given set (if only non-exclusive default values to speed up typing), the set being (made) available in some kind of configuration file. Examples I encountered so far include:
- appSettings keys
- navigation graph information for the User Interface Process (UIP) Application Block
- named permissions on buttons
- standard IDs for textboxes, buttons, etc.
In this case a type converter that reads an the web.config and returns the /configuration/appSettings/add/@key values solves the first demand. The step to a type converter base class that reads any xml file and provides a list of values according to some XPath expression is no rocket science. Given that base class any of those examples can be implemented using a simple derived class that only has to specify the file and XPath.
Consider the following (quite common) situation: You have an enumeration of certain values for some property of your component. The component shall act as base class and will be extended in different contexts. For example, a database action enumeration could include values like Save, Delete and Update.
The first approach that comes to mind would be to define a C# enumeration and the respective property. Afterwards your property can be set in the properties pane, the pane will automatically present a drop down list of the enumeration values, not allowing any other input. Of course working on the code level with eumerations is type safe and supported with intellisense.
However there is also a serious issue: The set of valid values for that property cannot be extended. .NET does not support something like inherritance of enumerations. If the derived class should need additional values one could either provide some special enumeration value in the base class for future use (some kind of “Custom”) and add an additional property to describe that custom value (making the act of describing the database action a two-stage process), or extend the enumeration with the custom value itself (spoiling the base class with information of derived functionality, making it visible to any other derived class and causing maintenance hurdles).
One could also revert to using a string instead of an enumeration. This would allow free choice of values and keep the base class clean of special cases. On the down side would be the lack of design time support, intellisense support (this could be solved with constants, yet this doesn’t help within the designer), and the need to remember all valid values in a given context. I see typos having a party…
Frankly, if these are the alternatives, I would prefer the spoiled enumeration.
However, a TypeConverter can help with these issues:
First, some attributes could describe the valid values of a property (they have to be specified somehow and an attribute looks good for me). A derived class could use one of these attributes to extend the set defined by the base class (say an attribute at the class level could take the name of the property and the additional values).
A type converter could then examine the property (the information is available through the context parameter) and the respective attributes along the inherritance hierarchy to build up a list of values which in turn causes the property grid to show a drop down list at design time. What’s more, the list will vary depending on the context, showing only the values that make sense in the given situation. Voilá, a string property with “extendable enumeration behaviour” at runtime.
Sometimes one needs to specify types (for dynamically created objects), methods (to be invoked dynamically), or properties (to get data from). All respective candidates (say all properties of an object) can be made available at designtime, given the right type converter.
Solution or project information
For navigation to another page it would be usefull to have a list of .aspx files in your project to select the page at design time. A type converter could get this list using the Visual Studio automation model.
This area is especially usefull if you are working with the Guidance Automation Toolkit (GAT) where type converters play a role in providing and converting informations for and from wizards. Examples include a list of projects, base classes, or the conversion of a project folder to a respective namespace for a new class.
Real type conversion
We should not forget the function type converters have by name. If you have a look at a windows form control at design time (the windows forms designer seems to make better use of this than the webforms designer), you will notice that you can type in something like “75;50″ in the properties pane for the Size property. You may also click on the little + and set the Width and Height property directly. The ability to set the values of contained properties (in this case Width and Height) on the object itself (in this case Size) comes with a … guess what? … type converter. In this case it converts the string with two numbers to an instance of the Size struct and vice versa.
Thus type converters can help to simplify the modification of properties of complex structs.
Code? Sorry, not this time. These are all real world examples from actual projects. I can share knowledge and experience but not customers’ code.