VB.NET에서는 컨트롤을 동적으로 생성하기 위해 필요한 클래스의 인스턴스를 생성하고 이를 Controls 컬렉션에 추가합니다. 동적으로 생성된 컨트롤의 이벤트 처리를 위해 VB.NET에서는 델리게이트와 AddHandler 연산자를 사용합니다:
예시 (VB.NET):
Dim btn As New Button() btn.Text = "클릭하세요!" 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("동적으로 생성된 버튼이 클릭되었습니다.") End Sub
클래식 VB6에서는 동적으로 컨트롤을 생성하고 이벤트를 처리하기 위해서만 컨트롤 배열(Control Arrays)을 사용해야 하며, 인디시는 개별 요소를 구분합니다:
예시 (VB6):
' 폼에는 Index = 0인 CommandButton 요소가 있어야 합니다. 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이 더 이상 존재하지 않지만 핸들러가 걸려있음
이야기
결제 단말기용 청구 시스템에서 결제 작업을 위한 동적 버튼이 패널에 생성되었습니다. 창을 닫은 후 남은 이벤트 핸들러가 가비지 컬렉션(Garbage Collection)을 방해했습니다. 일주일 동안 애플리케이션이 메모리 누수를 일으키며 서버가 중단되고 밤의 작업 중 프로세스를 수동으로 다시 시작해야 했습니다.
이야기
WinForms의 의료 시각화 프로젝트에서 많은 수의 "이미지 미리 보기"를 생성하기 위해 PictureBox가 생성되고 파기되었습니다. 개발자는 이벤트 핸들러를 제거하지 않았습니다. 애플리케이션이 20-30번 로드된 후 지연이 발생하기 시작했는데, 수천 개의 숨겨진 핸들러가 계속 남아 리소스 해제를 차단하고 있었습니다.
이야기
어린이를 위한 교육 애플리케이션 중 하나에서 퀴즈 버튼이 동적으로 생성되고 게임이 끝나면 폼에서 삭제되지만 이벤트가 RemoveHandler를 통해 구독 해지되지 않았습니다. 이로 인해 새로운 게임을 시작할 때 "유령" 코드 검사기가 실행되어 오래된 팝업과 점수 계산의 버그 및 일반적인 혼란이 발생했습니다.