Reputation: 39
If I create a control like so:
Dim fb As New Label
With fb
.Name = "newLabel"
.text = "some text"
<etc.>
Me.Controls.Add(fb)
End With
Now, if I wanted to change the text on that label during run time, I would normally do:
newLabel.text = "some other text"
Unfortunately, Visual Studio won't let me do that as 'newLabel' isn't defined until run time.
So, my question is: How do I reference a control created in such a way? (The only way I can think of is to loop through all controls until I find the one I'm looking for, but that seems a tad inefficient to me.)
Upvotes: 1
Views: 3720
Reputation: 54417
'newLabel' isn't defined until run time"
That isn't really accurate. You are confusing the object with a variable used to reference the object. When you add a control to a form in the designer, VS generates code to create and configure that control. It's much the same as the code you wrote and posted. You can see it in the designer code file, which you can access if you click the 'Shoe All Files' button in the Solution Explorer. That code includes a member variable to which the created object is assigned. You then use that member variable to refer to that object in code.
If you're creating controls at run time then you generally can't declare a member variable for each one to be assigned to because you don't know how many there will be. If you do know how many there will be then you probably ought to be adding them at design time. That means that you have two options:
Declare a single member variable that will refer to a collection of controls created at run time and then access then via name or index from that.
Access them by name from the Controls
collection of the form or other container control that you must add them to in order for them to be displayed.
Option 2 requires that you provide a unique name for each control when you create it. Option 1 doesn't require a name at all, although it doesn't preclude one.
Option 1 might look like this:
At the class level:
Private labels As New List(Of Label)
In a method somewhere:
For i = 0 To 9
Dim lbl As New Label
labels.Add(lbl)
Controls.Add(lbl)
Next
Later:
Dim lbl = labels(recordIndex)
Option 2 might look like this:
In a method somewhere:
For i = 0 To 9
Dim lbl As New Label With {.Name = "titleLabel" & i}
Controls.Add(lbl)
Next
Later:
Dim lbl = DirectCast(Controls("titleLabel" & recordIndex), Label)
Upvotes: 4