Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

HOW TO: Create a Web Control with an Expandable Property in the Designer by Using Visual Basic .NET


View products that this article applies to.

Summary

This step-by-step article demonstrates how to use Visual Basic .NET to create a custom Web control that has an expandable property. Properties can be expanded into subproperties for logical organization. The sample in this article demonstrates how to use a TypeConverter object of the ExpandableObjectConverter class and how to implement a custom TypeConverter object.

With the Microsoft Visual Studio .NET property browser, you can display nested properties. As a result, you can group properties more granularly and logically than categories. Nested properties are also available in both categorized and alphabetical sort mode. This helps to keep property lists compact.


Implement the Custom Control with ExpandableObjectConverter

  1. Follow these steps to create a new Visual Basic .NET Web Control Library project that is named ControlSampleLibrary:
    1. Start Microsoft Visual Studio .NET.
    2. On the File menu, point to New, and then click Project.
    3. In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Web Control Library under Templates.
    4. In the Name box, type ControlSampleLibrary.
  2. Rename the resulting project file (WebCustomControl1.vb) as EmployeeControl.vb.
  3. Replace the default implementation of the control with the following code:
    'System.ComponentModel provides the necessary attributes.
    Imports System.Web.UI
    Imports System.ComponentModel
    <DefaultProperty("EmployeeInfo"), ToolboxData("<{0}:EmployeeControl runat=server></{0}:EmployeeControl>")> _
    Public Class EmployeeControl
        Inherits System.Web.UI.WebControls.WebControl
    
        Private empInfo As New EmployeeInfo()
        'PersistenceMode.InnerProperty: Specifies that the property persists in
        'the ASP.NET server control as a nested tag. 
        'DesignerSerializationVisibility.Content: Specifies that a visual
        'designer serializes the contents of this property instead of the 
        'property itself. 
        <DefaultValue(""), Category("Custom"), _
        PersistenceMode(PersistenceMode.InnerProperty), _
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
        Public Property EmployeeInfo() As EmployeeInfo
            Get
                Return empInfo
            End Get
            Set(ByVal Value As EmployeeInfo)
                empInfo = Value
            End Set
        End Property
    
        Protected Overrides Sub Render(ByVal output As HtmlTextWriter)
            Dim outputString As String
            outputString = EmployeeInfo.FirstName & " " & _
                    EmployeeInfo.LastName & ", " & EmployeeInfo.EmployeeId & " " & "<br>"
            output.Write(outputString)
        End Sub
    End Class
    					
  4. On the Project menu, click Add Class. In the Name box, type EmployeeInfo.vb.
  5. Replace the default implementation of the EmployeeInfo class with the following code:
    Imports System.ComponentModel
    'ExpandableObjectConverter: Provides a type converter to convert expandable 
    'objects. It adds support for properties on an object to the methods and 
    'properties that TypeConverter provides.
    <TypeConverter(GetType(ExpandableObjectConverter))> _
    Public Class EmployeeInfo
        Private strFirstName As String = ""
        Private strLastName As String = ""
        Private iEmpId As Integer = 0
    
        <DefaultValue(""), NotifyParentProperty(True), RefreshProperties(RefreshProperties.Repaint)> _
        Property [FirstName]() As String
            Get
                Return strFirstName
            End Get
            Set(ByVal Value As String)
                strFirstName = Value
            End Set
        End Property
        <DefaultValue(""), NotifyParentProperty(True), RefreshProperties(RefreshProperties.Repaint)> _
        Property [LastName]() As String
            Get
                Return strLastName
            End Get
            Set(ByVal Value As String)
                strLastName = Value
            End Set
        End Property
        <DefaultValue(""), NotifyParentProperty(True), RefreshProperties(RefreshProperties.Repaint)> _
        Property [EmployeeId]() As Integer
            Get
                Return iEmpId
            End Get
            Set(ByVal Value As Integer)
                iEmpId = Value
            End Set
        End Property
    End Class
    					
  6. On the Build menu, click Build Solution to build the solution. Alternatively, press CTRL+SHIFT+B.

Test the Custom Control with ExpandableObjectConverter

  1. Follow these steps to create a new ASP.NET Web Application project:
    1. Start Visual Studio .NET.
    2. On the File menu, point to New, and then click Project.
    3. In the New Project dialog box, click Visual Basic Projects under Project Types, click ASP.NET Web Application under Templates, and then click OK.
  2. Follow these steps to add the EmployeeControl control to the Visual Studio .NET toolbox:
    1. In Design view, right-click the Web Forms tab in the toolbox, and then click Customize Toolbox.
    2. Click the .NET Framework Components tab.
    3. Click Browse, and then locate the folder that contains the ControlSampleLibrary.dll assembly. Select the file, and then click Open.
    4. After the reference to the control is added, click OK.
  3. Drag the EmployeeControl control from the toolbox to the WebForm1.aspx page.
  4. Click the EmployeeControl control. Notice that the Properties window displays the EmployeeInfo property. If you select the categorized option, the EmployeeInfo property is listed under the "custom" category.
  5. Expand the EmployeeInfo property into EmployeeId, FirstName, and LastName for separate entries, and then add some data to these properties.
  6. Build the solution, and then open the WebForm1.aspx page in your browser to test that your data is rendered.

Implement the Custom Control with Custom TypeConverter

Because the property browser only works with strings directly, the property browser relies on TypeConverter classes to convert those string values to the type that the property expects, and vice versa. TypeConverter classes also control expandability and allow complex types to work seamlessly with the property browser.

In this section, you implement a custom TypeConverter object that inherits from the ExpandableObjectConverter class. This custom TypeConverter converts an EmployeeInfo type to and from a string.
  1. On the Project menu, click Add Class to add a class that is named EmployeeInfoConverter.vb to ControlSampleLibrary.
  2. Replace the default implementation of the EmployeeInfoConverter class with the following code:
    Imports System.ComponentModel
    Imports System.Globalization
    Public Class EmployeeInfoConverter
        Inherits ExpandableObjectConverter
        'CanConvertFrom specifies which data types the converter can convert from.
        Public Overloads Overrides Function CanConvertFrom _
        (ByVal context As ITypeDescriptorContext, ByVal t As Type) As Boolean
            If (TypeOf t Is String) Then
                Return True
            End If
            Return MyBase.CanConvertFrom(context, t)
        End Function
        'ConvertFrom actually implements the conversion.
        Public Overloads Overrides Function ConvertFrom _
        (ByVal context As ITypeDescriptorContext, ByVal info As CultureInfo, _
         ByVal value As Object) As Object
    
            If (value Is GetType(String)) Then
                Try
                    Dim s As String = CType(value, String)
                    'Parse the format "FirstName LastName, (EmployeeId)"
    
                    Dim space As Integer = s.IndexOf(" ")
                    If Not (space = -1) Then
                        'Now that you have the space, get the FirstName.
                        Dim firstname As String = s.Substring(0, space)
                        Dim paren As Integer = s.LastIndexOf("(")
                        If (Not (paren = -1) And (s.LastIndexOf(")") = s.Length - 1)) Then
                            'Pick up the State.
                            Dim lastname As String = s.Substring(space + 1, paren - space - 1)
                            'Get the Zip.
                            Dim employeeid As Integer = Int32.Parse(s.Substring(paren + 1, s.Length - paren - 3))
                            Dim e As New EmployeeInfo()
                            e.EmployeeId = employeeid
                            e.FirstName = firstname.Trim()
                            e.LastName = lastname.Trim()
                            Return e
                        End If
                    End If
                Catch
                    ' If you got this far, complain that you
                    ' could not parse the string.
                    Throw New ArgumentException("Cannot convert '" + CType(value, String) + "' to type HomeAddress")
                End Try
            End If
            Return MyBase.ConvertFrom(context, info, value)
        End Function
        'CanConvertTo specifies which data types the converter can convert to.
        Public Overloads Overrides Function CanConvertTo _
        (ByVal context As ITypeDescriptorContext, ByVal destType As Type) As Boolean
            If (destType Is GetType(String)) Then
                Return True
            End If
            Return MyBase.CanConvertTo(context, destType)
        End Function
        'ConvertTo implements the actual conversion.
        Public Overloads Overrides Function ConvertTo _
        (ByVal context As ITypeDescriptorContext, _
         ByVal culture As CultureInfo, ByVal value As Object, _
         ByVal destType As Type) As Object
            If (destType Is GetType(String)) Then
                Dim e As EmployeeInfo = CType(value, EmployeeInfo)
                'Build the string as "Street, State, (Zip)"
                Dim result As String
                result = e.FirstName + " " + e.LastName + ", (" + e.EmployeeId.ToString() + ")"
                Return result
            End If
            Return MyBase.ConvertTo(context, culture, value, destType)
        End Function
    End Class
    					
  3. In the EmployeeInfo.vb module, change the following line
    <TypeConverter(GetType(ExpandableObjectConverter))> _
    						
    to:
    <TypeConverter(GetType(EmployeeInfoConverter))> _
    					
  4. On the Build menu, click Build Solution to build the solution. Alternatively, press CTRL+SHIFT+B.

Test the Custom Control with Custom TypeConverter

To test the new implementation, follow the same steps in the "Test the Custom Control with ExpandableObjectConverter" section of this article. Notice that the EmployeeInfo property is expandable and allows the user to handle this type either as subproperties or as a single string.

↑ Back to the top


Keywords: KB319626, kbhowtomaster, kbctrlcreate

↑ Back to the top

Article Info
Article ID : 319626
Revision : 6
Created on : 6/17/2003
Published on : 6/17/2003
Exists online : False
Views : 593