I'm trying to create a form with multiple labels, textboxes and buttons within a panel. The user will fill in their data and click a button that will create a new identical panel with the same labels, textboxes and buttons.

I read through the following thread in an effort to begin understanding the process:
http://www.daniweb.com/software-development/vbnet/threads/423618/adding-multiple-textboxes-to-a-form-control-array

I've attempted to try using some of the same code to do as I wish to no avail. Here is what I've written:

Public Sub frmOrderEntry2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
    '
    'This creates the label "Part No."
    Dim lblPrtNo As Label = New Label
    lblPrtNo.Name = "lblPrtNo"
    lblPrtNo.Text = "Part Number"
    lblPrtNo.ForeColor = Color.White
    lblPrtNo.Font = New System.Drawing.Font("Sans Serif", 9)
    lblPrtNo.Font = New System.Drawing.Font(lblPrtNo.Font, FontStyle.Regular)
    lblPrtNo.Location = New Point(6, 8)
    lblPrtNo.Size = New Size(77, 15)
    lblPrtNo.TextAlign = ContentAlignment.MiddleLeft
    lblPrtNo.Enabled = False
    AddHandler lblPrtNo.TextChanged, AddressOf lblPrtNo_Textchanged
    Me.Controls.Add(lblPrtNo)
    '
    'This generates the textbox for the user to enter the Part No.
    Dim txbPartNo As TextBox = New TextBox
    txbPartNo.Name = "txbPartNo"
    txbPartNo.Text = ""
    txbPartNo.ForeColor = Color.Black
    txbPartNo.BackColor = Color.White
    txbPartNo.Font = New System.Drawing.Font("Sans Serif", 10)
    txbPartNo.Font = New System.Drawing.Font(txbPartNo.Font, FontStyle.Bold)
    txbPartNo.Location = New Point(6, 26)
    txbPartNo.Size = New Size(263, 22)
    txbPartNo.TextAlign = ContentAlignment.MiddleLeft
    txbPartNo.Cursor = Cursors.Hand
    txbPartNo.AcceptsReturn = True
    txbPartNo.AcceptsTab = True
    txbPartNo.TabIndex = 10
    txbPartNo.Enabled = True
    AddHandler txbPartNo.TextChanged, AddressOf txbPartNo_Textchanged
    Me.Controls.Add(txbPartNo)
     Private Sub lblPrtNo_Textchanged(ByVal sender As System.Object, ByVal e As EventArgs)
    Dim lblPrtNo As Label = DirectCast(sender, Label)
    Me.Text = lblPrtNo.Name & ": " & lblPrtNo.Text
    lblPrtNo.Show()

End Sub

Private Sub txbPartNo_Textchanged(ByVal sender As System.Object, ByVal e As EventArgs)
    Dim txbPartNo As TextBox = DirectCast(sender, TextBox)
    Me.Text = txbPartNo.Name & ": " & txbPartNo.Text
    txbPartNo.Show()

End Sub

So that I am clear, this is just one label and one textbox of a total of 11 labels, 11 textboxes and 3 buttons within the one panel that needs to be created.

When I run the above code, the form is empty. Nothing appears. What am I missing? Any suggestions as to how to fix this?

In advance, thanks for any help.

Don

P.S. I'm using Visual Basic (Visual Studio 2010 Express)

At line 34 you have

Me.Controls.Add(txbPartNo)

but you don't have an End Sub before the next statement. On my system (VB 2010), the statement

txbPartNo.TextAlign = ContentAlignment.MiddleLeft

is not valid. When I remove it and add the End Sub the code works fine. And just out of curiousity, why do you need a TextChanged event handler for a label control?

instead of declaring them at the sub level

Dim lblPrtNo As Label = New Label
Dim txbPartNo As TextBox = New TextBox

I think you need to declare them at the class level like this:

Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents Label1 As System.Windows.Forms.Label

One of the best ways to see all code you'll need, is to design the form you want to end up with, then look in the form.designer.vb file. Everything needed to create your controls with the properties that you've set is in there.

If you're going to be creating a lot of controls, you might want to consider putting the code for each one in a sub, in a public module. It makes your code much simpler to read, especially if you have to look at it months or years down the road.

Keep in mind that if you want to reference the controls other than from within the event handlers, you will need a variable to hold that reference. If you are creating an array of textboxes then Ii suggest you use an array to save the references. As tinstaafl says, declare the array at the class level as

Private TxtRefs(10) As TextBox

If I'm not mistaken in order to use them on the form, each one needs to be declared as Friend WithEvents first, then they can be added to an array or list or other type of collection.

I've never used the Friend declaration and I've never had a problem. I also don't use the With Events option. That doesn't mean I am doing it correctly.

Friend just makes them accessible throughout the current assembly (similar to Public, but not accessible outside the defining assembly). If the control does not need to be accessed outside of the control in which it is declared, then Private is fine. Friend is the VB default for autogenerated code; nothing magic about the access level, just what the VB team selected. In C#, the default is private.

The WithEvents statement just allows you to add the "Handles cntrl.Event" to an event handler method for the control. If you do not use WithEvents, you need to use the Addhandler statement to attach a event handler method.

Rev. Jim and Tinstallfl,

In reviewing my original post, I see that I pasted lines 35-38 in error (these are not really there in my original programming).

Your suggestion of removing "txbPartNo.TextAlign = ContentAlignment.MiddleLeft" did allow the program to run.

But what is not working is the color changes within the label. It is currently black when I need it to be white as I'm actually using a Dark Blue background. Thoughts?

I should also add, I just tried adding the Panel. It is failing to run as well. Here is what I've written:

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.BackColor = Color.DarkBlue
        Me.ForeColor = Color.White
        '
        'This creates the Panel
        Dim pnlOrderEntry As Label = New Label
        pnlOrderEntry.Location = New Point(12, 48)
        pnlOrderEntry.Size = New Size(1232, 126)
        pnlOrderEntry.Visible = True
        Me.Controls.Add(pnlOrderEntry)

        '
        'This creates the label "Part No."
        Dim lblPrtNo As Label = New Label
        lblPrtNo.Name = "lblPrtNo"
        lblPrtNo.Text = "Part Number"
        lblPrtNo.BackColor = Color.DarkBlue
        lblPrtNo.ForeColor = Color.White
        lblPrtNo.Font = New System.Drawing.Font("Sans Serif", 9)
        lblPrtNo.Font = New System.Drawing.Font(lblPrtNo.Font, FontStyle.Regular)
        lblPrtNo.Location = New Point(15, 9)
        lblPrtNo.Size = New Size(77, 15)
        lblPrtNo.Enabled = False
        lblPrtNo.Visible = True
        Me.Controls.Add(lblPrtNo)
        '
        'This generates the textbox for the user to enter the Part No.
        Dim txbPartNo As TextBox = New TextBox
        txbPartNo.Name = "txbPartNo"
        txbPartNo.Text = ""
        txbPartNo.ForeColor = Color.Black
        txbPartNo.BackColor = Color.White
        txbPartNo.Font = New System.Drawing.Font("Sans Serif", 10)
        txbPartNo.Font = New System.Drawing.Font(txbPartNo.Font, FontStyle.Bold)
        txbPartNo.Location = New Point(15, 26)
        txbPartNo.Size = New Size(263, 22)
        txbPartNo.Cursor = Cursors.Hand
        txbPartNo.AcceptsReturn = True
        txbPartNo.AcceptsTab = True
        txbPartNo.TabIndex = 10
        txbPartNo.Enabled = True
        txbPartNo.Visible = True
        AddHandler txbPartNo.TextChanged, AddressOf txbPartNo_Textchanged
        Me.Controls.Add(txbPartNo)
    End Sub

    Private Sub txbPartNo_Textchanged(ByVal sender As System.Object, ByVal e As EventArgs)
        Dim txbPartNo As TextBox = DirectCast(sender, TextBox)
        Me.Text = txbPartNo.Name & ": " & txbPartNo.Text
        txbPartNo.Show()
    End Sub
End Class

To restate, the forecolor (white) in the label isn't being changed and the Panel is not being created, and I've noticed that the change in locations haven't taken place. What am I missing?

Give this a try and see if it is what you expect.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.BackColor = Color.DarkBlue
        Me.ForeColor = Color.White
        '
        'This creates the Panel

        '*** changed label to panel like you have stated
        Dim pnlOrderEntry As Panel = New Panel
        pnlOrderEntry.Location = New Point(12, 48)
        pnlOrderEntry.Size = New Size(1232, 126)
        pnlOrderEntry.Visible = True
        '*** added this color just so that I could see it, In you don't set a property,
        ' it inherits it from it's Parent control
        pnlOrderEntry.BackColor = Color.Coral
        Me.Controls.Add(pnlOrderEntry)


         '*** add the remaining controls to the panel
        '
        'This creates the label "Part No."
        Dim lblPrtNo As Label = New Label
        lblPrtNo.Name = "lblPrtNo"
        lblPrtNo.Text = "Part Number"
        lblPrtNo.BackColor = Color.DarkBlue
        lblPrtNo.ForeColor = Color.White
        lblPrtNo.Font = New System.Drawing.Font("Sans Serif", 9)
        lblPrtNo.Font = New System.Drawing.Font(lblPrtNo.Font, FontStyle.Regular)
        lblPrtNo.Location = New Point(15, 9)
        lblPrtNo.Size = New Size(77, 15)
        lblPrtNo.Enabled = False
        lblPrtNo.Visible = True
        pnlOrderEntry.Controls.Add(lblPrtNo)
        '
        'This generates the textbox for the user to enter the Part No.
        Dim txbPartNo As TextBox = New TextBox
        txbPartNo.Name = "txbPartNo"
        txbPartNo.Text = ""
        txbPartNo.ForeColor = Color.Black
        txbPartNo.BackColor = Color.White
        txbPartNo.Font = New System.Drawing.Font("Sans Serif", 10)
        txbPartNo.Font = New System.Drawing.Font(txbPartNo.Font, FontStyle.Bold)
        txbPartNo.Location = New Point(15, 26)
        txbPartNo.Size = New Size(263, 22)
        txbPartNo.Cursor = Cursors.Hand
        txbPartNo.AcceptsReturn = True
        txbPartNo.AcceptsTab = True
        txbPartNo.TabIndex = 10
        txbPartNo.Enabled = True
        txbPartNo.Visible = True
        AddHandler txbPartNo.TextChanged, AddressOf txbPartNo_Textchanged
        pnlOrderEntry.Controls.Add(txbPartNo)
    End Sub

    Private Sub txbPartNo_Textchanged(ByVal sender As System.Object, ByVal e As EventArgs)
        Dim txbPartNo As TextBox = DirectCast(sender, TextBox)
        Me.Text = txbPartNo.Name & ": " & txbPartNo.Text
        txbPartNo.Show()
    End Sub
End Class

TnTinMN,

I made the changes you've suggested and I do see the Panel. Unfortunately though, the label and the TextBox are not inside the Panel and, if they were, they would be hidden (the Panel isn't transparent?). I have played around with the location settings to no avail.

This now prompts another question - should I build the Panel and the controls in the IDE and then "copy" and "paste" the Panel and it's controls below? If so, how do I do this?

Thanks again for the help.

You can open the designer file and expand the form designer code. You might have to tell the solution explorer to show all files. It's an icon at the top of the explorer

If you want the controls in the panel then you have to add them to the panel controls collection instead of the form controls collection as in

pnlOrderEntry.Controls.Add(lblPrtNo)

I think that the easiest thing for you to do would be design your Panel as a user control, since that sounds like what you are attempting to do anyways. Doing so, will give you the security of working in the IDE.

Go to the Project Menu and select "Add User Control". Design as you want and then execute a Build on the project. After that the user control should show up at the top of your ToolBox under the Tab "Your Applicatiopn Name - Components". Add it to your form like any other control. Just remember that if you need to change its design, first close your form that houses it, then edit the User Control and rebuild before opening the form up.

Rev. Jim,

I like the idea of "pnlOrderEntry.Controls.Add(lblPrtNo)". I've tried to use this to no avail. Here is what I've done:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim pnlOrderLine As New Panel()
        pnlOrderLine.Size = New Size(1445, 135)
        pnlOrderLine.Location = New Point(12, 53)
        pnlOrderLine.BorderStyle = BorderStyle.Fixed3D
        pnlOrderLine.ForeColor = Color.White
        pnlOrderLine.Visible = True
        Me.Controls.Add(pnlOrderLine)
        '
        'This creates the label "Part No."
        Dim lblPrtNo As New Label()
        lblPrtNo.Name = "lblPrtNo"
        lblPrtNo.Text = "Part Number"
        lblPrtNo.BackColor = Color.DarkBlue
        lblPrtNo.ForeColor = Color.White
        lblPrtNo.Font = New System.Drawing.Font("Sans Serif", 9)
        lblPrtNo.Font = New System.Drawing.Font(lblPrtNo.Font, FontStyle.Bold)
        lblPrtNo.Location = New Point(15, 56)
        lblPrtNo.Size = New Size(77, 15)
        lblPrtNo.Enabled = False
        lblPrtNo.Visible = True
        pnlOrderLine.Controls.Add(lblPrtNo)
        Me.Controls.Add(lblPrtNo)
        '
        'This generates the textbox for the user to enter the Part No.
        Dim txbPartNo As New TextBox()
        txbPartNo.Name = "txbPartNo"
        txbPartNo.Text = ""
        txbPartNo.ForeColor = Color.Black
        txbPartNo.BackColor = Color.LightYellow
        txbPartNo.Font = New System.Drawing.Font("Sans Serif", 10)
        txbPartNo.Font = New System.Drawing.Font(txbPartNo.Font, FontStyle.Bold)
        txbPartNo.Location = New Point(15, 72)
        txbPartNo.Size = New Size(263, 22)
        txbPartNo.Cursor = Cursors.Hand
        txbPartNo.AcceptsReturn = True
        txbPartNo.AcceptsTab = True
        txbPartNo.TabIndex = 10
        txbPartNo.Enabled = True
        txbPartNo.Visible = True
        AddHandler txbPartNo.TextChanged, AddressOf txbPartNo_Textchanged
        pnlOrderLine.Controls.Add(txbPartNo)
        Me.Controls.Add(txbPartNo)
    End Sub

    Private Sub txbPartNo_Textchanged(ByVal sender As System.Object, ByVal e As EventArgs)
        Dim txbPartNo As TextBox = DirectCast(sender, TextBox)
        Me.Text = txbPartNo.Name & ": " & txbPartNo.Text
        txbPartNo.Show()
    End Sub

Am I adding this line correctly as you've suggested? The label and TextBox are now hidden behind the panel. I need them inside/on top of the panel.

Thanks for your help.

Don

I don't think you need to add the controls to the form, just to the panel.

tinstaafl,

I moved the Panel coding to the bottom and added the controls to the panel as suggested. It seems to work. Now the only issue to resolve is that of the back coloring and fore coloring of the controls themselves. These don't seem to work correctly. The labels have the correct background coloring but the letters are still black (they need to be white). Some of the TextBoxes need to be light yellow and these are white. Any thoughts there as to why these aren't being changed through the coding?

Thanks again for the help. If you can't tell, I'm a novice at this.

Don

I'm playing with it right now. In the meantime I'll mention that you shouldn't add the controls to both the panel and form collections. The form contains the panel control and the panel control contains the label and text controls.

Don't disable the label. Replace your code with

Dim lblPrtNo As New Label()
lblPrtNo.Name = "lblPrtNo"
lblPrtNo.Text = "Part Number"
lblPrtNo.BackColor = Color.DarkBlue
lblPrtNo.ForeColor = Color.White
lblPrtNo.Font = New Font("Sans Serif", 9, FontStyle.Bold)
lblPrtNo.Location = New Point(15, 56)
lblPrtNo.Size = New Size(77, 15)
pnlOrderLine.Controls.Add(lblPrtNo)

and it will work the way you want.

Rev. Jim,

Removing "lblPrtNo.Enable = False" did the trick.

I think now the last question will be: How do I now lock those textboxes that need to be locked? Some of these will just hold data in them that will come from a database. Therefore these boxes are not meant to be changed or edited. Those like "txbPrtNo" will be changed and should be unlocked. This is where I thought "Enable = True or False" would be appropriate as I couldn't find another way of locking it. Thoughts here??

By the way... You guys are awesome..... Thanks so much for the help here!

Don

Set the ReadOnly property to true.

Alternatively, you could use a label with autosize false, border fixed3d, background white. It'll look like a textbox but it will only display data.

I like the "ReadOnly" property setting. I'll give that a whirl.

Thanks again!!

Rev. Jim,

For what it's worth, I was more interested in ensure that those textboxes that needed to be locked were locked. I wasn't concerned with the labels.

Again, thanks for your input and help. It has been extremely value. I've learned a lot!

Gentlemen,

Given all great work you've given to help me, it has dawned on me that I now need to imbed the "line panel" within a larger "main panel" as I need to add a vertical scroll bar so that I can add as many lines as needed.

Using the same logic to create the original "line panel", I've added the following code in hopes that it would add the additional line panels into the "main panel". Here's what I've written:

' This set the order line panel within the main panel
        'Adding to main panel
        pnlMainPanel.Controls.Add(pnlOrderLine)
        pnlMainPanel.Visible = True
        'Adding to Form i.e. me
        Me.Controls.Add(pnlOrderLine)

It has failed. While the "panel" is created, it is behind the main panel. This makes me wonder if I need some kind of "AddHandler" or some other command to ensure these additional line panels are created within the main panel.

Do any of you have some thoughts or ideas? I've also added this question via another posting. You can read it at http://www.daniweb.com/software-development/vbnet/threads/448318/adding-multiple-panels-within-a-main-panel-via-code#post1937021 if you'd like to read or respond there.

Again, thanks for the help.

Don

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.