I need to build a number of forms in Visual Basic, but doing it manually take a lot of time. As an experiment I wound like to find out if I could generate forms with a number of Parameters, but I can't find a way to Code a Form. For example how would I Declare and Initialize Buttons, Label, Text Boxes, etc. and code them into Flow Layout or Table Layout. Do I build it in a Class or Form.vb or Module?
Please let me know, if its is possible or not.
CodePudding user response:
Here is an example of how to create controls dynamically in WinForms and add them to a container control. I also show you how to hook up an event handler. To test the code, create a new Form and add a panel to it called "Panel1". Then paste this code into the .vb file. You could add support for a lot more control types.
This extension method is useful, to make sure WinForms destroys the controls when you clear them from the container (needs to go into its own file)
Module ExtensionMethods
<Extension()>
Sub Clear(ByVal controls As Control.ControlCollection, ByVal dispose As Boolean)
For ix As Integer = controls.Count - 1 To 0
If dispose Then
controls(ix).Dispose()
Else
controls.RemoveAt(ix)
End If
Next
End Sub
End Module
This code shows how to create controls dynamically
''' <summary>
''' Function for creating a textbox and adding it to a control
''' </summary>
''' <param name="Container">The container control to add the textbox to</param>
''' <param name="Name">The Name (Id) of the TextBox (must be unique)</param>
''' <param name="LabelText">The text of the label to create to go with it</param>
''' <param name="Top">The Top (y) position of the TextBox</param>
''' <param name="Left">The Left (x) position of the TextBox</param>
''' <param name="Value">The value of the TextBox</param>
''' <returns></returns>
Private Function AddTextBox(ByRef Container As Control, Name As String, LabelText As String, Top As Integer, Left As Integer, Value As String) As TextBox
Dim tb As New TextBox With {.Name = Name, .Top = Top, .Left = Left, .Text = Value}
Dim lbl As New Label With {.Name = Name & "_lbl", .Top = Top, .Left = Left - 150, .Text = LabelText}
Container.Controls.Add(lbl)
Container.Controls.Add(tb)
Return tb
End Function
''' <summary>
''' Function for creating a button and adding it to a control
''' </summary>
''' <param name="Container">The container control to add the button to</param>
''' <param name="Name">The Name (Id) of the Button (must be unique)</param>
''' <param name="Text">The Text of the Button</param>
''' <param name="Top">The Top (y) position of the Button</param>
''' <param name="Left">The Left (x) position of the Button</param>
''' <returns></returns>
Private Function AddButton(ByRef Container As Control, Name As String, Text As String, Top As Integer, Left As Integer) As Button
Dim btn As New Button With {.Name = Name, .Text = Text, .Top = Top, .Left = Left, .Visible = True, .AutoSize = True}
Container.Controls.Add(btn)
Return btn
End Function
''' <summary>
''' A click handler for our Button
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub button_Click(sender As Object, e As EventArgs)
Dim tb_Name As TextBox = Panel1.Controls.Find("tb_Name", False)(0)
Dim tb_EmailAddress As TextBox = Panel1.Controls.Find("tb_EmailAddress", False)(0)
MessageBox.Show("Name: " & tb_Name.Text & " Email Address: " & tb_EmailAddress.Text)
End Sub
''' <summary>
''' A sub for building our form
''' </summary>
Private Sub BuildForm()
' Clear existing controls
' This is only really needed in an ASP.NET solution where
' you are re-rendering the controls in the PreRender
' event because things have changed since the OnInit event.
' Although, if you need to change the form based on what
' was put into it (like a dynamic questionnaire) then this would
' also be applicable in a WinForms scenario.
Panel1.Controls.Clear(True)
' Create a "Name" textbox
AddTextBox(Panel1, "tb_Name", "Your Name", 10, 200, "")
' Create an "EmailAddress" textbox
AddTextBox(Panel1, "tb_EmailAddress", "Your EmailAddress", 40, 200, "")
' Create a button to Save Changes
Dim SaveButton As Button = AddButton(Panel1, "btn_Save", "Save Changes", 70, 200)
' Add a handler to the button click event
AddHandler SaveButton.Click, AddressOf button_Click
End Sub
''' <summary>
''' Build the form as soon as it's shown
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
BuildForm()
End Sub