How can I create a loop that reveals a certain number of labels? - vb.net

I want to be able to reveal and then populate a certain number of labels. The inefficient way would be to SELECT CASE on the number of labels required and then populate these in turn. I am looking for something like this:
For i = 1 to RequiredNumOfLabels
Label & i.visible = true
Label & i.text = DataTable.Rows(i).Item(2)
Next
Thank you.
EDIT:
For i = 1 To NumberOfItems
Dim lbl = Controls("lbl" & i)
lbl.Visible = True
lbl.Text = CStr(DataTable.Rows(i).Item(2))
Next
I think the line
Dim lbl = Controls("lbl" & i)
is the problem as after the line is executed, lbl still equals nothing.
The reasoning behind it is that I was trying to create an invoice generator in vb.net and I was hoping that this would be a simple way to do it - count the amount of items in the order, populate the labels with the names of the items, reveal that many labels.

If your label controls are really in order like that, you can try just referencing them from a list:
Dim myLabels As New List(Of Label)
myLabels.Add(Label1)
myLabels.Add(Label2)
Then just update them:
For i as Integer = 1 to myLabels.Count
myLabels(i - 1).Visible = True
myLabels(i - 1).Text = DataTable.Rows(i).Item(2).ToString
Next

You can get controls by name through the forms Controls property
For i = 1 To RequiredNumOfLabels
Dim lbl = TryCast(Controls("Label" & i), Label)
If lbl IsNot Nothing Then
lbl.Visible = True
lbl.Text = CStr(DataTable.Rows(i).Item(2))
End If
Next
Since you get an object of type Control, you have to cast it to Label.
UPDATE
It seems that you only use properties that are defined in Control anyway. Therfore you can simplify the code to
For i = 1 To RequiredNumOfLabels
Dim lbl = Controls("Label" & i)
lbl.Visible = True
lbl.Text = CStr(DataTable.Rows(i).Item(2))
Next

Related

Adding labels and other controls to a groupbox dynamically in vb.net not working?

So I've been having problems adding labels from a record structure into a groupbox that stack below each other vertically. I could use a Flow Layout Panel but I have multiple labels I need to add from data in a record structure which I want to be able to scroll later with a vertical scrollbar as the autoscroll will only work with one panel only, and not all of them.
For some reason the program puts only one label in, and the others don't seem to be visible even though they have been created (I used a messagebox to check). Could someone please help me to put them in, as I am fairly new to programming and need help.
For context, the program loads 'materials' from an xml file and stores it in a record structure, then this bit of the program creates labels and radio buttons dynamically and puts it in a groupbox, so that it can be arranged manually on a pretty grid that will all become scrollable by using a scrollbar later.. Because the data I am working with is all related, and can have strings of multiple sizes (names and suppliers of materials for example) I didn't want to attempt to add whitespace to make the grid work but with a single label (not that the others would show beneath the first for some reason)
CODE:
'sets up Labels for editing materials
prgFunctions.loadMat()
Dim counter As Integer
Dim newMatIDLabel(numMatFile) As Label
Dim newMatRdb(numMatFile) As RadioButton
Dim lastPos As Integer
'testing to see if materials load GET RID OF LATER
' For counter = 1 To numMatFile
'ListBox1.Items.Add(materials(counter).matName)
' Next
'create the labels with information
For counter = 1 To numMatFile
'ID
newMatIDLabel(counter) = New Label
newMatIDLabel(counter).Name = "lblMatIDNum" & counter
newMatIDLabel(counter).Text = materials(counter).matID
newMatIDLabel(counter).Parent = gbxMaterials
' MsgBox(newMatIDLabel(counter).Name & " " & newMatIDLabel(counter).Text)
Next
'create the checkboxes NOW RADIO BUTTONS
For counter = 1 To numMatFile
newMatRdb(counter) = New RadioButton
newMatRdb(counter).Name = "chkMatSelectNum" & counter
newMatRdb(counter).Text = ""
newMatRdb(counter).Parent = gbxMaterials
Next
'matID locations
lastPos = 10
For counter = 1 To numMatFile
'SOMEHOW MOVE IT INTO THE GROUPBOX INSTEAD, as issues arise everywhere
newMatIDLabel(counter).Location = New Point(7, lastPos + 10)
lastPos = lastPos + 10
Next
Why not just:
lastPos = 10
For counter = 1 To numMatFile
Dim label As New Label
label.Name = "chkMatSelectNum" & counter
label.Text = materials(counter).matID
label.Location = New Point(7, lastPos)
label.Visible = True
gbxMaterials.Controls.Add(label)
lastPos += label.Height
Next
Based on F0r3v3r-A-N00b's answer:
The label has a height of 23, so it seems it is hiding the others.
This works for me:
Dim lastPos As Integer = 20
For counter As Integer = 1 To numMatFile
Dim label As New Label
label.Name = "chkMatSelectNum" & counter
label.Text = materials(counter).matId
label.AutoSize = True
label.Visible = True
label.Location = New Point(7, lastPos)
gbxMaterials.Controls.Add(label)
lastPos += 17
Next

Why can't I get textbox.text values from code generated textboxes

I have a project where I have a form "userform1" which only has a "GO" button and an "EXIT" button on it to begin with. I solicit user input via an inputbox for a number. I use code to then populate the form with that number of labels and textboxes and display the form to allow editting of the created textboxes. Everything works fine up to this point.
I then want the "GO" button to populate an array with the textbox.text values for use elsewhere. This is where I am having a problem.
I tried retrieving the text like I normally do (something like; Xstring = UserForm1.Box1.Text), that didn't work. So then I cycled thru the form controls; UserForm1.Controls.index(), looking for my Textbox .names to confirm they existed. I found them, so I singled one out, index(3), .name = "Box1". See below:
Dim tText As String
tText = UserForm1.Box1.Text
MsgBox tText
returns an ERROR, 'method or data member not found'
But if I change it to this:
Dim x As Object
Dim tText As String
Set x = UserForm1.Controls.Item(3)
tText = x.Text
MsgBox tText
The msgbox returns the .text value
So, QUESTION is, why can't I simply address it normally? I don't want to have to go through all the extra steps to figure out index numbers vs names to populate my array.
for reference, below is partial code of my sub for creating labels/textboxes:
For i = Data(x, 1) To z
Lab = "forms.label.1"
Box = "forms.textbox.1"
Set newlabel = UserForm1.Controls.Add(Lab)
Set newtextbox = UserForm1.Controls.Add(Box)
lbl1 = ("Label" + CStr(i))
With newlabel
.Name = lbl1
.Caption = "No. " + CStr(i)
.Left = Data(x, 3)
.top = top
.Height = 20
.Width = 30
End With
lbl2 = ("Box" + CStr(i))
With newtextbox
.Name = lbl2
.Text = CStr(i)
.Left = (Data(x, 3) + 35)
.top = top
.Height = 20
.Width = 36
End With
top = top + 25
Next i
UserForm1 has no method or data member of that name before run-time. Therefore the VBA interpreter cannot interpret what is meant.
You can nevertheless access the item via through its collection of child controls indexed on either index number or control name, like:
Dim myTxtBox As MSForms.TextBox
Me.Controls.Add bstrProgId:="Forms.Textbox.1", Name:="My Runtime Textbox"
Set myTxtBox = Me.Controls("My Runtime Textbox")
myTxtBox.Text = "Hello"
After reading the comments from Cor_Blimey, this is what I now have working in the code for retrieving my program generated textbox.text data:
Dim i As Integer, num As Integer, ctr As Integer
Dim oCntl As Object
Dim tText() as String
num = UserForm1.Controls.Count
ReDim tText(num)
For Each Control In UserForm1.Controls 'loops thru each control
If TypeOf Control Is TextBox Then
ctr = ctr + 1
tText(ctr) = Control.Text
End If
Next Control
ReDim Preserve tText(ctr)
The .text is being written to the array sequentially (by index#, the order textboxes were created)
In the future, I might consider 2 values in the array, 1 for .name and 1 for .text, just to be sure.

label doesn't appear on dynamically created form vb.net

I'm staring at my code for hours now and I don't understand what's going on. I'm creating a form with a number of checkboxes and labels, based on a textbox value from another form.
This is the code:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim lb As Label
Dim cb1 As CheckBox
Dim cb As CheckBox
Dim i As Integer
Dim j As Integer
For i = 1 To CInt(Aantal.Text) - 1
indivwoningen.Width = indivwoningen.Size.Width + 21
indivwoningen.Button1.Location = New Point(indivwoningen.Button1.Location.X + 21, indivwoningen.Button1.Location.Y)
lb = New Label
indivwoningen.Controls.Add(lb)
lb.Text = i + 1
lb.Font = indivwoningen.Label23.Font
lb.Location = New Point(indivwoningen.Label23.Location.X + 21 * i, indivwoningen.Label23.Location.Y)
For j = 1 To 18
cb1 = New CheckBox
indivwoningen.Controls.Add(cb1)
cb = indivwoningen.Controls.Find("CheckBox" & j & "00", False)(0)
cb1.Location = New Point(cb.Location.X + 21 * i, cb.Location.Y)
cb1.Width = cb.Width
cb1.Text = cb.Text
If i < 10 Then
cb1.Name = "CheckBox" & j & "0" & i
Else
cb1.Name = "CheckBox" & j & i
End If
Next
Next
indivwoningen.Show()
End Sub
The created form has got two flaws:
Only the first created label is visible
The checkboxes aren't properly aligned.
I don't understand what's going on. Can someone help me?
EDIT: Here are pictures before I create extra controls and after
Set the Autosize property to True for the labels and set the Height of the checkboxes to the same height of your reference checkbox
For i = 1 To CInt(Aantal.Text) - 1
....
lb = New Label
indivwoningen.Controls.Add(lb)
lb.Text = i + 1
lb.Font = indivwoningen.Label23.Font
lb.Autosize = True
lb.Location = New Point(indivwoningen.Label23.Location.X + 21 * i, indivwoningen.Label23.Location.Y)
For j = 1 To 18
cb1 = New CheckBox
indivwoningen.Controls.Add(cb1)
cb = indivwoningen.Controls.Find("CheckBox" & j & "00", False)(0)
cb1.Location = New Point(cb.Location.X + 21 * i, cb.Location.Y)
cb1.Width = cb.Width
cb1.Height = cb.Height
cb1.Text = cb.Text
If i < 10 Then
cb1.Name = "CheckBox" & j & "0" & i
Else
cb1.Name = "CheckBox" & j & i
End If
Next
Next
Well, for the checkbox the explanation seems to be easy. The new checkbox has, by default, an Heigth of 24 pixels while the one drawn on the form as a smaller Height. So, because the check square is centered inside the Height of the Checkbox it appears to be not aligned to the reference checkbox.
For the labels the problem is of the same kind. Without setting the Autosize, the labels are created with a default size of 100x23 pixels. This means that the label with text "2" extends its size to cover the position of the labels with text "3","4","5","6", while the label with text "3" covers the label with text "7" and so on.
In any case setting AutoSize seems to be the default behavior, followed also in the Form.Designer.vb file where the controls are created following your design time instructions.
You could also try to set the Size of the dynamically created labels to the same size of the reference label and the effect is the same.

VB manipulate lots of labels inside panel

So i have like 100 labels inside a panel and i need to to change their texts.I Tried an for and i tried Tab Index like an array without success, any ideas how I can select and change properties of these labels?
Sub setCartela(ByVal numeros As Integer)
For cont As Integer = 0 To numeros Step 1
//change labels text inside panel
Next
End Sub
Try like this ...
Dim i as Integer = 1
For Each ctrl As Control In Panel1.Controls
If ctrl.GetType.ToString = "System.Windows.Forms.Label" Then
ctrl.Text = "Text" & format(i)
End If
i += 1
Next
try this code :
dim _countLbl as integer = 1
For each Lbl as Label in Panel1.Controls.Oftype(Of Label)()
Lbl.text="Label" & _countLbl
_countLbl += 1
Next

How to concat variable integer in control name in vb.net

Now I have a database and pull out that data and display it to form,i have a sequence of groupbox and radiobuttons, in each groupbox (groupbox1,groupbox2,etc...) there are 2 radio buttons namely rdbtn1Yes and rdbtn1No (then it increment +1 in next Groupbox). now i use for loop to go through every groupboxes and radio buttons. And this is my code:
Dim sqlda As New SqlDataAdapter("SELECT * FROM table1 WHERE column1= '" & lblWONo.Text & "'", Constr)
Dim sqlds As New DataSet
sqlds.Clear()
sqlda.Fill(sqlds)
If sqlds.Tables(0).Rows.Count > 0 Then
With sqlds.Tables(0).DefaultView.Item(0)
txtDateCreated.Value = .Item(0).ToString
txtComments.Text = .Item(1).ToString
'check column if it contain FALSE/TRUE value
'then toggle the radiobutton state to TRUE
'In this part i know there is another/easiest way to checked radio buttons to TRUE value
'and this is my code using looping (below):
If .Item(2) = False Then
rdbtn1No.Checked = True
Else
rdbtn1Yes.Checked = True
End If
If .Item(3) = False Then
rdbtn2No.Checked = True
Else
rdbtn2Yes.Checked = True
End If
If .Item(4) = False Then
opt3N.Checked = True
Else
opt3Y.Checked = True
End If
End With
End If
SAMPLE CODE FOR LOOPING:
Dim itemNo As Integer
Dim rdbtnSet As Integer = 1
Dim grpboxCnt As Integer = 1
For Each grpbx As GroupBox In Me.Controls.OfType(Of GroupBox)()
For itemNo = 2 To sqlds.Tables(0).Columns.Count
If .Item(itemNo) = True Then
rdbtn & rdbtnSet & "Yes".checked = True 'I want to be this way but we know that this is not working or its not the proper way. That is my problem.
Else
rdbtn & rdbtnSet & "No".checked = True 'I want to be this way but we know that this is not working or its not the proper way. That is my problem.
End If
Next
rdbtnSet += 1
grpboxCnt += 1
Next
Thats all. Thank you in advance!
Think about the use of a dictionary (id, control) to store your controls. Then iterate the dictionary and set your state.