Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleMake a type converter in Visual Basic .NET
DescriptionThis example shows how to make a type converter in Visual Basic .NET.
KeywordsTypeConverter, type converter, PropertyGrid, Properties window, property, VB .NET
CategoriesControls
 
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.

 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated