Если я создам такой элемент управления:
Dim fb As New Label
With fb
.Name = "newLabel"
.text = "some text"
<etc.>
Me.Controls.Add(fb)
End With
Теперь, если бы я хотел изменить текст на этой метке во время выполнения, я бы обычно сделал:
newLabel.text = "some other text"
К сожалению, Visual Studio не позволяет мне это сделать, поскольку newLabel не определен до времени выполнения.
Итак, мой вопрос: как мне ссылаться на элемент управления, созданный таким образом? (Единственный способ, о котором я могу думать, - это перебрать все элементы управления, пока я не найду тот, который ищу, но мне это кажется немного неэффективным.)
'newLabel' isn't defined until run time"
Это не совсем так. Вы путаете объект с переменной, используемой для ссылки на объект. Когда вы добавляете элемент управления в форму в конструкторе, VS генерирует код для создания и настройки этого элемента управления. Это очень похоже на код, который вы написали и опубликовали. Вы можете увидеть это в файле кода дизайнера, доступ к которому можно получить, нажав кнопку «Загрузить все файлы» в обозревателе решений. Этот код включает переменную-член, которой назначается созданный объект. Затем вы используете эту переменную-член для ссылки на этот объект в коде.
Если вы создаете элементы управления во время выполнения, вы, как правило, не можете объявить переменную-член для каждой из них, которая будет назначена, потому что вы не знаете, сколько их будет. Если вы знаете, сколько их будет, вероятно, вам следует добавить их во время разработки. Это означает, что у вас есть два варианта:
Объявите одну переменную-член, которая будет ссылаться на коллекцию элементов управления, созданных во время выполнения, а затем обращаться к ней через имя или индекс из нее.
Доступ к ним по имени из коллекции формы или другого контейнерного элемента управления Controls
, в который вы должны добавить их, чтобы они отображались.
Вариант 2 требует, чтобы вы указали уникальное имя для каждого элемента управления при его создании. Вариант 1 вообще не требует имени, хотя и не исключает его.
Вариант 1 может выглядеть так:
На уровне класса:
Private labels As New List(Of Label)
Где-то в методе:
For i = 0 To 9
Dim lbl As New Label
labels.Add(lbl)
Controls.Add(lbl)
Next
Потом:
Dim lbl = labels(recordIndex)
Вариант 2 может выглядеть так:
Где-то в методе:
For i = 0 To 9
Dim lbl As New Label With {.Name = "titleLabel" & i}
Controls.Add(lbl)
Next
Потом:
Dim lbl = DirectCast(Controls("titleLabel" & recordIndex), Label)
Спасибо большое. Многому учусь.
У вас уже есть переменная, которую вы используете:
fb
. Но это не может быть локальная переменная, ее нужно переместить вверх и сделать членом класса. Или, может быть, вы предпочитаете также находить его динамически: Dim fb = DirectCast (Me.Controls ("newLabel"), Label)