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
- Follow these steps to create a new Visual Basic .NET Web Control Library project that is named ControlSampleLibrary:
- Start Microsoft Visual Studio .NET.
- On the File menu, point to New, and then click Project.
- In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Web Control Library under Templates.
- In the Name box, type ControlSampleLibrary.
- Rename the resulting project file (WebCustomControl1.vb) as EmployeeControl.vb.
- 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
- On the Project menu, click Add Class. In the Name box, type EmployeeInfo.vb.
- 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
- On the Build menu, click Build Solution to build the solution. Alternatively, press CTRL+SHIFT+B.
Test the Custom Control with ExpandableObjectConverter
- Follow these steps to create a new ASP.NET Web Application project:
- Start Visual Studio .NET.
- On the File menu, point to New, and then click Project.
- In the New Project dialog box, click Visual Basic Projects under Project Types, click ASP.NET Web Application under Templates, and then click OK.
- Follow these steps to add the EmployeeControl control to the Visual Studio .NET toolbox:
- In Design view, right-click the Web Forms tab in the toolbox, and then click Customize Toolbox.
- Click the .NET Framework Components tab.
- Click Browse, and then locate the folder that contains the ControlSampleLibrary.dll assembly. Select the file, and then click Open.
- After the reference to the control is added, click OK.
- Drag the EmployeeControl control from the toolbox to the WebForm1.aspx page.
- 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.
- Expand the EmployeeInfo property into EmployeeId, FirstName, and LastName for separate entries, and then add some data to these properties.
- 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.
- On the Project menu, click Add Class to add a class that is named EmployeeInfoConverter.vb to ControlSampleLibrary.
- 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
- In the EmployeeInfo.vb module, change the following line
to:
<TypeConverter(GetType(ExpandableObjectConverter))> _
<TypeConverter(GetType(EmployeeInfoConverter))> _
- On the Build menu, click Build Solution to build the solution. Alternatively, press CTRL+SHIFT+B.