|
|
Title | Make a type converter in Visual Basic .NET |
Description | This example shows how to make a type converter in Visual Basic .NET. |
Keywords | TypeConverter, type converter, PropertyGrid, Properties window, property, VB .NET |
Categories | Controls |
|
|
One of the cooler new controls in VB .NET is the PropertyGrid. If you set the control's SelectedObject property to an object, the control displays the object's properties much as the Properties window does in the IDE.
However, if the object contains properties that are also objects, then the PropertyGrid displays a string representation of the property object. If the object has a ToString method, the grid uses that. If the object has no ToString method, it inherits a ToString method from the Object class that simply gives the object's class name. This will geneally be something like project_name.class_name.
To help the PropertyGrid understand how to display the property object, you need to give it a type converter. This is a class that can convert the object to and from a textual representation.
The example program's Person class contains an Address property that is an object of type StreetAddress. The following code shows the StreetAddress class. Notice how the TypeConverter attribute indicates that this class's type converter is the StreetAddressConverter class. The class has a constructor that takes a street address, city, and state as parameters to make initializing objects easy, and it has a ToString method to produce a string representation. This representation has the form "street,city,state" as in "123 Crash Ave,Bugsville,CA".
|
|
<TypeConverter(GetType(StreetAddressConverter))> _
Public Class StreetAddress
Public Sub New()
End Sub
Public Sub New(ByVal new_street As String, ByVal _
new_city As String, ByVal new_state As String)
m_Street = new_street
m_City = new_city
m_State = new_state
End Sub
Public Overrides Function ToString() As String
Return m_Street & "," & m_City & "," & State
End Function
Private m_Street As String
Public Property Street() As String
Get
Return m_Street
End Get
Set(ByVal Value As String)
m_Street = Value
End Set
End Property
Private m_City As String
Public Property City() As String
Get
Return m_City
End Get
Set(ByVal Value As String)
m_City = Value
End Set
End Property
Private m_State As String
Public Property State() As String
Get
Return m_State
End Get
Set(ByVal Value As String)
m_State = Value
End Set
End Property
End Class
|
|
The following code shows the StreetAddressConverter class, which inherits from TypeConverter. Its CanConvertFrom and CanConvertTo methods indicate whether the converter can convert objects from or to certain data types. In this example, CanConvertFrom indicates that the converter can convert a string into a StreetAddress object and CanConvertTo indicates that the converter can convert a StreetAddress object into a string.
The ConvertFrom and ConvertTo methods perform the conversions. ConvertFrom splits a text representation into the street, city, and state fields, and uses them to create a new StreetAddress object. ConvertTo simply calls the object's ToString method.
The GetPropertiesSupported method should return True if the PropertyGrid should allow the user to view and edit any of the object's properties separately. This is how the PropertyGrid decides whether to display a plus sign to the left of the StreetAddress indicating that it has editable sub-properties. If GetPropertiesSupported returns False, then the PropertyGrid does not display the plus sign, displays the StreetAddress as a single string, and does not display the street, city, and state as their own separate entries.
The GetProperties method should return a collection of PropertyDescriptors describing the properties that should be separately editable. Normally you will use TypeDescriptor.GetProperties(value) to get a collection of PropertyDescriptors describing all of the object's properties but you could make a PropertyDescriptorCollection describing only some of the properties if you don't want to let the user view and edit them separately.
|
|
Public Class StreetAddressConverter
Inherits TypeConverter
Public Overloads Overrides Function _
CanConvertFrom(ByVal context As _
System.ComponentModel.ITypeDescriptorContext, ByVal _
sourceType As System.Type) As Boolean
If (sourceType.Equals(GetType(String))) Then
Return True
Else
Return MyBase.CanConvertFrom(context, _
sourceType)
End If
End Function
Public Overloads Overrides Function CanConvertTo(ByVal _
context As _
System.ComponentModel.ITypeDescriptorContext, ByVal _
destinationType As System.Type) As Boolean
If (destinationType.Equals(GetType(String))) Then
Return True
Else
Return MyBase.CanConvertTo(context, _
destinationType)
End If
End Function
Public Overloads Overrides Function ConvertFrom(ByVal _
context As _
System.ComponentModel.ITypeDescriptorContext, ByVal _
culture As System.Globalization.CultureInfo, ByVal _
value As Object) As Object
If (TypeOf value Is String) Then
Dim txt As String = CType(value, String)
Dim fields() As String = txt.Split(New Char() _
{","})
Try
Return New StreetAddress(fields(0), _
fields(1), fields(2))
Catch
Throw New InvalidCastException(value)
End Try
Else
Return MyBase.ConvertFrom(context, culture, _
value)
End If
End Function
Public Overloads 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.Equals(GetType(String))) Then
Return value.ToString()
Else
Return MyBase.ConvertTo(context, culture, _
value, destinationType)
End If
End Function
Public Overloads Overrides Function _
GetPropertiesSupported(ByVal context As _
ITypeDescriptorContext) As Boolean
Return True
End Function
Public Overloads Overrides Function GetProperties(ByVal _
context As ITypeDescriptorContext, ByVal value As _
Object, ByVal Attribute() As Attribute) As _
PropertyDescriptorCollection
Return TypeDescriptor.GetProperties(value)
End Function
End Class
|
|
With all this set up, the rest is automatic. The PropertyGrid displays the Person object's properties. It uses the StreetAddressConverter class to convert the StreetAddress property to and from a String representation.
(It's not clear to me why the PropertyGrid doesn't use reflection to automatically build a converter for the StreetAddress class. After all, that's what it does for the Person class. I guess this gives you more direct control but it would be a lot easier if there were a MakeConverter attribute to do this automatically.
For more information on type converters, see Implementing a TypeConverter by Paul Kimmel at CodeGuru.
There's lots more information about VB 2005 (although not type converters) in my book Visual Basic 2005 Programmer's Reference.
|
|
|
|
|
|