Performing Map Visualization
Normally the Properties window examines a property and displays an appropriate representation of the property's value based on the property's type. For text and numeric properties it displays a textual value, for colors it displays a color sample, and for enumerated types it displays the name of the selected value.
For properties of type image, such as a form's
BackgroundImage property, the Properties window displays a tiny thumbnail of the image and the name of the image resource stored in the property, for example,
WindowsApplication1.My.Resources.Resources.us_map.
The Properties window can also display a representation of object types by showing the object's property values separated by commas. For example, it might display a Font property as
Microsoft Sans Serif, 8.25pt and a Size property as
565, 430.
Finally, the Properties window can use custom type converters and editors to display values and allow you to edit them in the Properties window. For example, the
Anchor and
Dock properties for Windows Forms display special popup editors that let you set their values graphically.
The StateSelector control displays a special value for its Map property. The Properties window displays "(map)" if a map is loaded (See Figure 2) or "(none)" if no map is loaded.
|
|
The StateSelector control's
Map property has the datatype StatesMap. The Properties window doesn't really understand the StatesMap class, so it has no clue about how to display the
Map property's value.
The key to providing a custom display for a value in the Properties window is to make a type converter to translate a StatesMap value into a string. The first step is to add a TypeConverter attribute to the property's declaration. The following code shows the
Map property's definition:
Private m_Map As StatesMap = Nothing
<Category("Data")> _
<Description("The data describing the map borders.")> _
<Browsable(True)> _
<TypeConverter(GetType(StatesMapConverter))> _
<Editor(GetType(StatesMapEditor), GetType(UITypeEditor))> _
<DefaultValue(GetType(StatesMap), Nothing)> _
Public Property Map() As StatesMap
Get
Return m_Map
End Get
Set(ByVal value As StatesMap)
m_Map = value
DoAutoSize()
Me.Invalidate()
End Set
End Property
The control stores the property's value in the private variable
m_Map. The
Category and
Description attributes tell the Properties window which category should hold the property and what description to display. The
Browsable attribute indicates that developers should see the property in the Properties window.
The
TypeConverter attribute tells the Properties window what class it can use to convert the property to other datatypes such as strings. The
Editor and
DefaultValue attributes are useful for editing the property's value and are covered in the next section of this article.
The
Map property's code is straightforward. The
Get procedure simply returns the value in
m_Map. The
Set procedure saves a new value in
m_Map, and also calls the
DoAutoSize method (which sizes the control to fit its map if the
AutoSize property is
True). Finally, it invalidates the control to force it to redraw.
With the property definition in place, you need to provide the type converter class, in this case StatesMapConverter shown in the following code. The code is actually fairly simple, but it looks imposing, largely because the two overridden methods have huge parameter lists:
' Converts RegionMap objects for Properties window display.
Public Class StatesMapConverter
Inherits TypeConverter
' We can convert StatesMap objects into a string.
Public Overrides Function CanConvertTo( _
ByVal context As _
System.ComponentModel.ITypeDescriptorContext, _
ByVal destinationType As System.Type) As Boolean
If destinationType Is GetType(String) Then Return True
Return MyBase.CanConvertTo(context, destinationType)
End Function
' Convert a StatesMap object into a string.
Public Overrides Function ConvertTo( _
ByVal context As _
System.ComponentModel.ITypeDescriptorContext, _
ByVal culture As System.Globalization.CultureInfo, _
ByVal value As Object, _
ByVal destinationType As System.Type) As Object
If destinationType Is GetType(String) Then
If (value Is Nothing) Then
Return "(none)"
Else
Return "(map)"
End If
End If
Return MyBase.ConvertTo(context, culture, _
value, destinationType)
End Function
End Class
The StatesMapConverter class inherits from the TypeConverter base class and overrides two methods:
CanConvertTo and
ConvertTo. The
CanConvertTo function returns a Boolean to indicate whether the converter can convert a value from the property's type to another type. The overridden version returns
True only if the destination type is String, letting the Properties window know that the converter can convert a StatesMap into a String.
Function
ConvertTo does the actual conversion, converting a StatesMap object into a String. It first checks the destination data type, taking action only if it's converting the object into a String. The function returns either
(none) or
(map) depending on whether the StatesMap value is
Nothing or has a value.
That's all there is to it. If the
Map property's value is
Nothing, the type converter tells the Properties window to display
(none); otherwise the type converter tells the Properties window to display the value
(map).
Author's Note: Using a similar technique, you can use a type converter to display objects as compound values. For example, suppose the Contact class includes FirstName, LastName, and Phone properties. You could build a type converter to convert the set of individual property values into a string containing the properties separated by commas. By making the type converter inherit from the ExpandableObjectConverter class, you can let the user expand the property into sub-properties, much as you can expand a Font or Size property. While this article doesn't explain how to display object values in this way, my book Expert One-on-One Visual Basic 2005 Design and Development does. |