Update Dynamically created text box by name withought looping through all controls (VB) - vb.net

I have a project that creates several buttons dynamically along with a slider (two splitters in a panel).
For the purpose of this lets call the slider "slider9001" and the label "label9001". Each set of control's last 4 digits are different.
Currently I'm looping through all of the controls and looking for a label with the last 4 digits of the slider. This seems incredibly inefficient, especially considering there will be over 100 labels and 40-50 sliders on the form.
Does anyone know of a simple and more efficient way of accessing a dynamically created label
I should mention the slider will be used to update the label

If you know the name of the control you can get a reference to it
Dim lbl as label =
ctype(me. Controls("label9001"),label)

As the labels are generated, store a reference to each one in a dictionary. Use the digits as the key. When you need a label, simply retrieve it from the dictionary. The same approach will work for the sliders as well.
dim labels as new Dictionary(of string, Label)
' add generated labels to dictionary
dim lbl = labels("9001")

Outstanding! Since I already know the name
Dim lbl as label = ctype(me. Controls("label9001"),label)
Worked perfectly. Thanks Much!!!

Related

Fill a boolean array from checkbox control array

My program creates an array of checkboxes at runtime as shown below:
For Looper = 0 To 36
Dim Ex1ConfigCheck As New CheckBox
frmSetup.Controls.Add(Ex1ConfigCheck) ' Add Control to from
Ex1ConfigCheck.Top = (Looper + 45) + (Looper * 18) ' Set Location
Ex1ConfigCheck.Left = 210
Ex1ConfigCheck.Text = Setup.ExCheckName(Looper) ' Set Text property from strArray
Next
This is where I don't know how to proceed.
I would like to fill a boolean array (ex. MyBoolean(37)) with the value of Ex1configCheck().Checked. The reason I would like to fill another array is because I need to be able to reference the value of the checkboxes in other parts of the code but can't access them until they are created. Also, I plan on saving the array out to a binary file.
Could someone point me in the right direction please?
If there are no other CheckBoxes in the same container as those ones then you can do this:
Dim flags = Me.Controls.OfType(Of CheckBox)().
Select(Function(cb) cb.Checked).
ToArray()
If the controls are in a different container than the form itself, replace Me with that container.
As suggested by #Jimi, you could also create a List(Of CheckBox) and assign that to a field, populating it when you create the controls. You can then use that list instead of creating one on demand:
Dim flags = myCheckBoxList.Select(Function(cb) cb.Checked).
ToArray()
Of course, if you know exactly how many CheckBoxes you are going to be adding, why do you need to wait until run time to create them? Why can't you create them at design time and then modify them at run time? You usually only create controls at run time if you don't know how many there will be until run time, but that seems not to be the case here.
Thanks all for your answers and comments. I always have a fear of being roasted when I ask what some may consider a simple question online.
I have found an alternative way of accomplishing my task. Instead of creating 8 "Arrays" of checkboxes, I have learned of a very simple control available called "CheckedListBox".
I really didn't need to create the checkboxes at runtime but was trying to find an easier way to create 8 groups of 37 checkboxes without having to manually name and set the properties of each one during design. I also wanted to be able to index them in my code to be able to update and read the value using simple loops. I could have done this by creating arrays of CheckBox but again, I would have had to manually initialize the arrays.
Once I found the CheckedListBox, I was able to accomplish what I want very quickly. I only had to set the properties of the 8 "groups" (CheckedListBox's) and fill them using the items property. The ListBox essentially created a List like Jimi suggested automatically and I can index thru each list with a loop as desired. Jimi's suggestion actually lead me to finding the CheckedListBox while I was searching for more information on using "List(of CheckBox)".
Sometimes talking to others helps me find the right questions to ask. Google was able to figure out what I wanted when I searched for "List(of CheckBox)". (:

VB.Net Selecting LineShape

In Vb.Net, I'm dinamycally creating several textbox and labels. I'm naming them ex. VLabel1, VLabel2, VLabel3 ... and then I use CType and a variable to use them.
Dim VarName as String
Dim i as Integer
Dim MyLabel as Label
i=0
VarName = ("VLabel" & i.ToString)
MyLabel = CType(Panel1.Controls(VarName), Label)
Now I'm adding lines using LineShape (I can't use label having height of 1 because my lines are diagonals). Can I use a similar way to select a specific line or do I have to use a loop in my ShapeContainer and compare names until I find the one I want?
Thank you,
Stephane
do I have to use a loop in my ShapeContainer and compare names until I find the one I want?
What do you think the Controls(VarName) does? It has to lookup the control by name, too. If you're comfortable with that, you can write a method in your form that does the same thing.
But a better option for both the LineShapes and the Labels is use List(Of LineShape) and a List(Of Label). When you create a dynamic control and add or remove it from your form, also add or remove it form your list. Then you can reference these items by index, without needing to build a name string. You'll also have less casting this way.
Another option to index them by name is to use Dictionary(Of String,Lineshape) and Dictionary(Of String, Label). A couple of helper subs can handle adding/removing where needed and adding/removing to the appropriate Dictionary. With this you also eliminate the need for casting as the actual objects are of the correct type already.
Even better yet, since Shapes aren't part of the standard library, I would suggest learning how to draw the lines directly on to your form.
I've never done it, but it should be possible to actually create the lines as controls, by creating a class that inherits from the Control class and overriding the Paint sub to draw the line.

Write individual listbox items into different text boxes and repeat until all text boxes are full

I'm programming in Visual Basic.
I have one form.
Form 1 contains:
nameTextBox
addNameButton
namesListBox
generateButton
week1TextBox
week2TextBox
week3TextBox
week4TextBox
The user needs to go to Form 1 and type a name in the text box, then add the name to the List Box. The user will add 4 names to the List Box. So, the ListBox will contain the names: Adam, Brenda and Carol.
When the generateButton is clicked, the 3 names have to be written to the text boxes in that order. So week1TextBox should contain "Adam", week2TextBox should contain "Brenda", etc... but once the last name (in this case "Carol") is written into the text box, the loop should start over. Ultimately, there may be up to 50 week text boxes (so week50TextBox). So the loop needs to repeat over and over.
As there is a lack of source code in your question, I'm really not sure exactly how the layout should look, I can only offer some advice/suggestions.
I would recommend creating your listbox control, input textbox, and button to add names to the listbox. In addition to these, though, also add a scrollable panel. (Not sure what the exact term for that control is in VB.net; it's been a long time since I've worked with that language.) Because it sounds like there might be a variable number of items on the panel, when the user goes to generate the list of names, I would use the following rough pseudocode:
Dim OutputTexts As New ArrayList ' This is only here if you want to work with these textboxes later
Private Sub CreateOutput() Handles btnGenerate.Click
pOutputPanel.Controls.Clear()
OutputTexts.Clear()
Dim NextX As Integer = 0 ' Pretty much unnecessary value, but included in case you want to mess with this
Dim NextY As Integer = 0
For i As Integer = 0 To Convert.ToInt32(txtWeekCount.Text)
Dim txtName As New TextBox
txtName.Text = lbNameList.Item(i Mod lbNameList.Items.Count)
txtName.Location = new Point(NextX, NextY) ' Play with this as necessary
NextY += 50 ' Play with this as necessary
OutputTexts.Add(txtName)
pOutputPanel.Controls.Add(txtName)
Next
End Sub
Again, this is very much pseudocode, so I would not encourage copying and pasting, but give it a read, make sure you understand all of it, and then try implementing something similar. There might be an easier way to do it, but I have not programmed in VB.NET in probably over 2 years (at least). Nonetheless, the most important thing in here is the following line: lbNameList.Item(i Mod lbNameList.Items.Count). By Mod-ing your indexing variable, you will be accessing items sequentially, and then repeating from the start of the ListBox items collection once i is out of range.
I would also encourage you to dynamically generate your TextBox controls as needed rather than manually adding in 50 or more TextBox controls.

How to add a control after another dynamically?

What i am looking for is how to add another control(say a textbox directly under another textbox) that is added through code rather than the designer. I can get it to work using the .height property of the control then adding another 10-20 to it
dim space as integer
space += textbox1.height + 10
however, is there a way to do this on the location rather than the height? In this case, if I want to add a textbox at the very end of the frame or groupbox without having to add additional in between. Since the location takes two parameters(x,y), is it possible to place controls based on another controls location?
Does this help? (not clear what you are after, but yes, you can set the Location or Size all at once):
Dim thisTB as new TextBox
thisTB.Location = new Point(xSpot, ySpot)
thisTB.Size = otherTB.Size
Me.Controls.Add(thisTB)

Resizing a dynamically created label to fit the text inside it?

I'm creating a label dynamically, and then adding text to it dynamically (and the amount of text added to it will be different each time). So, the label needs to always be the same width as the text inside it.
This happens by default when creating a label in the Windows Designer. But when creating a label dynamically, it appears to be "set" at a specific width, regardless of how much text is in it (which means that it often "cuts off" some of the text).
So... any idea how I can get the dynamically created label to always stay the same width as the text inside it?
If you want to do it manually, you can do something like this, every time you change the text:
Dim g As Graphics = Label1.CreateGraphics()
Label1.Width = CInt(g.MeasureString(Label1.Text, Label1.Font).Width)
However, it's much easier to simply set the label's AutoSize property to True and let the label do the work for you.
Label1.AutoSize = True