W Visual Basic (VB.NET) do dynamicznego tworzenia kontrolek używa się tworzenia instancji potrzebnej klasy i dodawania jej do kolekcji Controls. Do obsługi zdarzeń dla dynamicznie utworzonych kontrolek w VB.NET używane są delegaty i operator AddHandler:
Przykład (VB.NET):
Dim btn As New Button() btn.Text = "Kliknij mnie!" 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("Dynamicznie utworzony przycisk został kliknięty.") End Sub
W klasycznym VB6 dynamiczne tworzenie i obsługa zdarzeń dla kontrolek możliwe jest tylko poprzez tablice kontrolne (Control Arrays), gdzie indeksy rozróżniają poszczególne elementy:
Przykład (VB6):
' Na formularzu powinien być element CommandButton z Index = 0 Load Command1(1) Command1(1).Visible = True Private Sub Command1_Click(Index As Integer) MsgBox "Przycisk z indeksem " & Index & " został naciśnięty!" End Sub
Należy pamiętać, że w VB.NET nie ma pojęcia tablic kontrolnych jak w VB6 — obsługę zdarzeń dla dynamicznie utworzonych kontrolek zapewnia tylko mechanizm delegatów oraz AddHandler/RemoveHandler.
Pytanie: "Co się stanie, jeśli zapomnimy wywołać RemoveHandler dla zdarzeń dynamicznie utworzonej kontrolki przy jej usunięciu? Jakie mogą być konsekwencje?"
Odpowiedź: Jeśli zapomnimy wywołać RemoveHandler przed usunięciem kontrolki, odniesienie do procedury obsługi pozostanie w pamięci, co doprowadzi do wycieku pamięci (memory leak), a czasami — do próby dostępu do już zniszczonego obiektu lub formularza, co spowoduje wyjątek.
Przykład:
' Zapomniany RemoveHandler: ' AddHandler btn.Click, AddressOf SomeHandler ' Controls.Remove(btn) ' btn już nie istnieje, ale handler wisi
Historia
W systemie billingowym dla terminali płatniczych tworzono dynamiczne przyciski na panelu do operacji płatności. Po zamknięciu okna pozostałe procedury obsługi eventów przeszkadzały w zbieraniu śmieci (Garbage Collection). Przez tydzień aplikacja powodowała wycieki pamięci, prowadząc do awarii serwerów i konieczności ręcznego ponownego uruchamiania procesu w nocy.
Historia
W projekcie wizualizacji medycznej na WinForms do generowania dużej ilości "podglądów obrazów" tworzono i niszczono PictureBox. Programista nie usunął procedur obsługi zdarzeń. Po 20-30 załadowaniach aplikacja zaczęła zwalniać: okazało się, że tysiące ukrytych procedur kontynuowały wiszenie, blokując zwalnianie zasobów.
Historia
W jednej z aplikacji edukacyjnych dla dzieci dynamicznie formowano przyciski quizów i po zakończeniu gry usuwano je z formularza, ale zdarzenia nie były odpisywane poprzez RemoveHandler. Z tego powodu przy starcie nowej gry dochodziło do "duchowych" aktywacji kodów kontrolujących, co prowadziło do przestarzałych popupów, błędów w naliczaniu punktów i ogólnego zamieszania.