How to dynamically add a control without hardcoding the control type in Visual Basic (311321)



The information in this article applies to:

  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET (2003)
  • Microsoft Visual Basic .NET (2002)

This article was previously published under Q311321
For a Microsoft Visual C# version of this article, see 815780.
For a Microsoft Visual Basic 6.0 version of this article, see 190670.

SUMMARY

This step-by-step article describes how to add a control to a form dynamically in Microsoft Visual Basic 2005 or in Microsoft Visual Basic .NET, and how to respond to the control's events.

Step-by-step example

This section describes how to create a project that demonstrates how to add a control to a form dynamically in Visual Basic 2005 or in Visual Basic .NET, and how to respond to the control's events.
  1. Create a new Visual Basic 2005 or Visual Basic .NET Windows Application project. Form1 is added to the project by default.

    Note You must change the code in Visual Basic 2005. By default, Visual Basic creates two files for the project when you create a Windows Forms project. If the form is named Form1, the two files that represent the form are named Form1.vb and Form1.Designer.vb. You write the code in the Form1.vb file. The Windows Forms Designer writes the code in the Form1.Designer.vb file. The Windows Forms Designer uses the partial keyword to divide the implementation of Form1 into two separate files. This behavior prevents the designer-generated code from being interspersed with your code.

    For more information about the new Visual Basic 2005 language enhancements, visit the following Microsoft Developer Network (MSDN) Web site: For more information about partial classes and the Windows Forms Designer, visit the following MSDN Web site:
  2. Add the following code to the top of the Form1 Code window:
    Imports System.Reflection
  3. Place two Command Buttons and one ComboBox on Form1 near the bottom of the form. You will add controls dynamically in the top of the form. Change the Name and Text properties of these controls as follows:
    ControlNameText property
    Button1btnAddControlAdd Control
    Button2btnRemoveControlRemove Control
    Combobox1cboControlTypesSelect Control Type
  4. Paste the following code into Form1's "general declaration" section after the "Inherits" statement:
        Dim DynTreeview As TreeView, DynTextBox As TextBox
        Dim DynListBox As ListBox
        Dim ControlObject As Control
  5. Paste the following code after the "Windows Form Designer generated code" region:
    Private Sub Form1_Load(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles MyBase.Load
           cboControlTypes.Items.AddRange(New Object() _
            {"TreeView", "ListBox", "TextBox"})
    End Sub
    
    Sub AddControl(ByVal ControlName As String, ByVal ControlType As String)
            Dim asm As [Assembly]
            asm = GetType(Form).Assembly
            ControlObject = asm.CreateInstance(ControlType)
            ControlObject.Name = ControlName
            ControlObject.Location = New System.Drawing.Point(20, 20)
            Me.Controls.Add(ControlObject)
            If ControlType.EndsWith("TreeView") Then
                DynTreeview = ControlObject
                DynTreeview.Width = 200
                DynTreeview.Height = 120
                DynTreeview.Nodes.Add(New TreeNode("Root"))
                DynTreeview.Nodes(0).Nodes.Add("FirstChild")
                DynTreeview.Nodes(0).Nodes.Add("SecondChild")
                DynTreeview.ExpandAll()
                AddHandler DynTreeview.AfterSelect, _
                AddressOf DynTree_AfterSelect
            ElseIf ControlType.EndsWith("ListBox") Then
                DynListBox = ControlObject
                DynListBox.Width = 200
                DynListBox.Height = 120
                DynListBox.Items.AddRange(New Object() _
                {"Apples", "Banana", "Oranges"})
                AddHandler DynListBox.SelectedIndexChanged, _
                AddressOf DynCtrl_Event
            ElseIf ControlType.EndsWith("TextBox") Then
                DynTextBox = ControlObject
                DynTextBox.Width = 200
                DynTextBox.Text = "Dynamically Added Textbox."
                AddHandler DynTextBox.DoubleClick, AddressOf DynCtrl_Event
            End If
    End Sub
    
    Private Sub btnAddControl_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnAddControl.Click
            Dim CtrlType As String
            If Not ControlObject Is Nothing Then
                btnRemoveControl.PerformClick()
            End If
            If cboControlTypes.SelectedIndex < 0 Then
                MessageBox.Show("Please select a Control Type to add.")
                Exit Sub
            End If
            CtrlType = "System.Windows.Forms." & _
            cboControlTypes.SelectedItem.ToString
            Me.AddControl("myControl", CtrlType)
    End Sub
    
    Private Sub DynCtrl_Event(ByVal sender As System.Object, _
        ByVal e As System.EventArgs)
            If sender.GetType.ToString.EndsWith("ListBox") Then
                MessageBox.Show("The item you selected is: " & _
                DynListBox.SelectedItem.ToString)
            ElseIf sender.GetType.ToString.EndsWith("TextBox") Then
                Clipboard.SetDataObject(DynTextBox.Text)
                MessageBox.Show("The Text is copied to the clipboard.")
            End If
    End Sub
    
    Private Sub btnRemoveControl_Click(ByVal sender As System.Object, _
          ByVal e As System.EventArgs) Handles btnRemoveControl.Click
          Me.Controls.Remove(ControlObject)
          ControlObject = Nothing
    End Sub
    
    Private Sub DynTree_AfterSelect(ByVal sender As Object, _
          ByVal e As TreeViewEventArgs)
          MessageBox.Show("The Node you clicked on is: " & e.Node.Text)
    End Sub
  6. Save your project. On the Debug menu, click Start, and then run your project.
  7. In the combo box, click TreeView as the control type, and then click the Add Control button. Note that a new TreeView control is added. Click any node to test the AfterClick event of the TreeView control.

Code discussion

  • In this sample, the ComboBox control contains the list of control types to be added dynamically. You populate this list in the form's Load procedure.
  • You declared three specific control objects in the "general declaration" section so that you can use the individual functionality of these control objects in your program. Another benefit of declaring specific control types is that you can access IntelliSense while you are programming.
  • In the btnAddControl_Click procedure, you check to determine if there is another control that is already loaded. If so, you remove the existing control and then add the new control that was selected in the combo box. You also make sure that the combo box has a valid selection. If the selection is not valid, the program generates a message box and exits the procedure without processing further statements. If the selection is valid, you call the AddControl procedure with appropriate parameters.
  • In the AddControl procedure, you declared asm as a System.Reflection.Assembly type. The GetType(Form) statement returns the type object of the Form type. You then use the Assembly method of this object to retrieve an instance of the assembly in which the Form class is defined. After assembly, the asm object is created. You use its CreateInstance method with a ControlType string parameter to create an instance of the control. After the control is created, you add it to the current form by using the Me.Controls.Add method. Then, by using the EndsWith method of the String class, you check the type of control that is passed to this procedure as the second argument. Depending on the control type, you set the individual properties of the control in the If...ElseIf...End If block. You use an AddHandler statement to connect the specific event of the dynamically added control with the handling procedure. For ListBox and TextBox controls, you connected SelectedIndexChanged and DoubleClick events with the DynCtrl_Event procedure. For the TreeView control, you used a separate procedure named DynTree_AfterSelect to connect the control with the AfterSelect event of the TreeView control.
  • The event-handling procedure for the TreeView control requires a unique signature from the other two controls. The second argument type in the DynTree_AfterSelect procedure is of type TreeViewEventArgs; for the DynCtrl_Event procedure you use type System.EventArgs. The TreeViewEventArgs type provides additional information such as the properties of the selected node.
You could have used the WithEvents keyword in the declaration of the control instead of using the AddHandler statement for programming the event handlers manually. In that case, you would have used separate event handlers for each control (as are used for the design time controls on the form).

REFERENCES

  • For more information about adding a control on a form if the control type is hardcoded, see the "Adding Controls to Windows Forms" topic in the Visual Studio 2005 or Visual Studio .NET Help documentation.
  • For more information about adding event handlers, refer to the "Writing Event Handlers" topic in the Visual Studio 2005 or Visual Studio .NET Help documentation.

Modification Type:MinorLast Reviewed:10/3/2006
Keywords:kbvs2005swept kbvs2005applies kbHOWTOmaster KB311321 kbAudDeveloper