0
votes

I want to create a simple Winform application that contains multiple blocks .

Each block is a FlowLayoutPanel container that holds the following form controls: (Image attached for reference)

  1. Label
  2. TextBox
  3. ListBox
  4. CheckBox

Sample UI

Sample Code

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class NXOpenWinForm
Inherits System.Windows.Forms.Form

Public Sub New()
    InitializeComponent()
    NXOpenUI.FormUtilities.SetApplicationIcon(Me)
    NXOpenUI.FormUtilities.ReparentForm(Me)
End Sub

'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    Try
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
        End If
    Finally
        MyBase.Dispose(disposing)
    End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.  
'Do not modify it using the code editor.


'<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
    Me.FlowLayoutPanel1 = New System.Windows.Forms.FlowLayoutPanel()
    Me.Label1 = New System.Windows.Forms.Label()
    Me.TextBox1 = New System.Windows.Forms.TextBox()
    Me.ListBox1 = New System.Windows.Forms.ListBox()
    Me.CheckBox1 = New System.Windows.Forms.CheckBox()
    Me.FlowLayoutPanel1.SuspendLayout()
    Me.SuspendLayout()
    '
    'FlowLayoutPanel1
    '
    Me.FlowLayoutPanel1.Controls.Add(Me.Label1)
    Me.FlowLayoutPanel1.Controls.Add(Me.TextBox1)
    Me.FlowLayoutPanel1.Controls.Add(Me.ListBox1)
    Me.FlowLayoutPanel1.Controls.Add(Me.CheckBox1)
    Me.FlowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top
    Me.FlowLayoutPanel1.Location = New System.Drawing.Point(0, 0)
    Me.FlowLayoutPanel1.Name = "FlowLayoutPanel1"
    Me.FlowLayoutPanel1.Padding = New System.Windows.Forms.Padding(2)
    Me.FlowLayoutPanel1.Size = New System.Drawing.Size(641, 105)
    Me.FlowLayoutPanel1.TabIndex = 0
    '
    'Label1
    '
    Me.Label1.Anchor = System.Windows.Forms.AnchorStyles.Left
    Me.Label1.AutoSize = True
    Me.Label1.Location = New System.Drawing.Point(5, 46)
    Me.Label1.Name = "Label1"
    Me.Label1.Size = New System.Drawing.Size(39, 13)
    Me.Label1.TabIndex = 0
    Me.Label1.Text = "Label1"
    '
    'TextBox1
    '
    Me.TextBox1.Anchor = System.Windows.Forms.AnchorStyles.Left
    Me.TextBox1.Location = New System.Drawing.Point(50, 5)
    Me.TextBox1.Multiline = True
    Me.TextBox1.Name = "TextBox1"
    Me.TextBox1.Size = New System.Drawing.Size(169, 94)
    Me.TextBox1.TabIndex = 1
    '
    'ListBox1
    '
    Me.ListBox1.Anchor = System.Windows.Forms.AnchorStyles.Left
    Me.ListBox1.FormattingEnabled = True
    Me.ListBox1.Location = New System.Drawing.Point(225, 5)
    Me.ListBox1.Name = "ListBox1"
    Me.ListBox1.Size = New System.Drawing.Size(291, 95)
    Me.ListBox1.TabIndex = 2
    '
    'CheckBox1
    '
    Me.CheckBox1.Anchor = System.Windows.Forms.AnchorStyles.Left
    Me.CheckBox1.AutoSize = True
    Me.CheckBox1.Location = New System.Drawing.Point(522, 44)
    Me.CheckBox1.Name = "CheckBox1"
    Me.CheckBox1.Size = New System.Drawing.Size(81, 17)
    Me.CheckBox1.TabIndex = 3
    Me.CheckBox1.Text = "CheckBox1"
    Me.CheckBox1.UseVisualStyleBackColor = True
    '
    'NXOpenWinForm
    '
    Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    Me.ClientSize = New System.Drawing.Size(641, 351)
    Me.Controls.Add(Me.FlowLayoutPanel1)
    Me.Name = "NXOpenWinForm"
    Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
    Me.Text = "Test App"
    Me.FlowLayoutPanel1.ResumeLayout(False)
    Me.FlowLayoutPanel1.PerformLayout()
    Me.ResumeLayout(False)

End Sub

Friend WithEvents FlowLayoutPanel1 As Windows.Forms.FlowLayoutPanel
Friend WithEvents Label1 As Windows.Forms.Label
Friend WithEvents TextBox1 As Windows.Forms.TextBox
Friend WithEvents ListBox1 As Windows.Forms.ListBox
Friend WithEvents CheckBox1 As Windows.Forms.CheckBox
End Class

In the image above, I have created a block manually. I wish to generate n-number of such blocks. Is it possible to generate these blocks dynamically during run-time? Not sure if I can use a simple for/while loop to achieve this.

1
You can do this in a simple for/while loop - just add to the containing control Controls collection. Depending on your use case it might be preferable to use a repeating or list control and make use of its Template instead if your composite control is data-bound. - Filburt
@Filburt - I am facing issues using a for loop inside InitializeComponent(). It will be great help if you could provide me a sample code . - Roshan Shiveshwar
As you discovered, you cannot do this in the InitializeComponent() - register an EventHandler for the OnLoad event and put your loop there. However I'd still suggest to use a databound control ... even if you just bind a list of names to put into your Label. - Filburt
you can also save this combination of controls as a usercontrol and add it to your form like any other control. Or is there a spicific reason not to do that? - AConfusedSimpleton
Yes, it's possible to generate controls at run-time simply in a for loop. But before doing so, make sure you are not trying to reinvent DataGridView. Also you can consider using a DataRepeater control. If the pattern for each row is the same, you can use UserControl. Also take a look at this post. - Reza Aghaei

1 Answers

0
votes

You can do what you want in 2 steps

  1. You must define a UserControl named RowUserControl (this is example) that contains all controls that you need (Textbox, Listbox, Label, Checkbox).

  2. You can then add dynamically this new control in your code

Example

Dim i as Integer
Dim ctl as RowUserControl
For i = 1 to 10
    ctl = new RowUserControl()
    ctl.Name = "Row-" & CStr(i)
    Me.Controls.Add(ctl)
Next i

Ideally, you can add first a Panel in your Form and add all necessary rows in this panel so that it contains only RowUserControl controls.

Don't forget to enable vertical and horizontal scrollbars !