В Visual Basic (VB.NET) для динамического создания контролов используется создание экземпляра нужного класса и добавление его в коллекцию Controls. Для обработки событий для динамически созданных контролов в VB.NET применяются делегаты и оператор AddHandler:
Пример (VB.NET):
Dim btn As New Button() btn.Text = "Click me!" btn.Location = New Point(40, 40) Me.Controls.Add(btn) AddHandler btn.Click, AddressOf Button_Click Private Sub Button_Click(sender As Object, e As EventArgs) MessageBox.Show("Dynamically created button clicked.") End Sub
В классическом VB6 динамически создавать и обрабатывать события для контролов возможно только через массивы контролов (Control Arrays), где индексы различают отдельные элементы:
Пример (VB6):
' На форме должен быть элемент CommandButton с Index = 0 Load Command1(1) Command1(1).Visible = True Private Sub Command1_Click(Index As Integer) MsgBox "Кнопка с индексом " & Index & " нажата!" End Sub
Следует помнить, что в VB.NET нет понятия массивов контролов как в VB6 — обработку событий у динамически созданных контролов обеспечивает только механизм делегатов и AddHandler/RemoveHandler.
Вопрос: "Что произойдет, если забыть вызвать RemoveHandler для событий динамически созданного контрола при его уничтожении? Какие последствия это может иметь?"
Ответ: Если забыть вызвать RemoveHandler перед удалением контрола, ссылка на обработчик останется в памяти, что приведет к утечке памяти (memory leak), а иногда — к попытке обращения к уже уничтоженному объекту или форме, что вызовет исключение.
Пример:
' Забытый RemoveHandler: ' AddHandler btn.Click, AddressOf SomeHandler ' Controls.Remove(btn) ' btn больше нет, но обработчик висит
История
В биллинговой системе для терминалов оплаты создавались dynamic-кнопки на панели для операций оплаты. После закрытия окна оставшиеся обработчики событий мешали сборке мусора (Garbage Collection). В течение недели приложение вызывало memory leaks, приводя к падению серверов и потребности вручную перезапускать процесс поверх ночных операций.
История
В проекте медицинской визуализации на WinForms для генерации большого количества "image preview" создавались и уничтожались PictureBox. Разработчик не убирал обработчики событий. Спустя 20-30 загрузок приложения начинало тормозить: оказалось, что тысячи скрытых обработчиков продолжали висеть, блокируя освобождение ресурсов.
История
В одном из educational-приложений для детей динамически формировались кнопки викторин и после завершения игры удалялись с формы, но события не отписывались через RemoveHandler. Из-за этого при старте новой игры происходили "призрачные" срабатывания кода-чекеров, приводившие к устаревшим popup'ам, багам с начислением баллов и общей путанице.