2012-06-19 2 views
1

현재 작업중인 다른 프로젝트에 필요하기 때문에 어셈블리에있는 클래스가 있습니다. 하나의 클래스는 클래스 팩토리를 호출하고 클릭 이벤트 핸들러가 연결되어야하는 컨트롤 그룹을 만들고, 특정 기능을 기반으로 다형성 동작을 결정하는 알고리즘이 있지만 상대적으로 적합하지 않습니다. 이벤트 처리기가 내 어셈블리의 일부가 아닌 특정 폼을 열어야하고이 폼이이 "팩토리"클래스를 필요로하기 때문에. 순환 참조를 만들지 않고 양식의 핸들러 이벤트를 본질적으로 "위임"할 수있는 방법이 있습니까?순환 참조를 작성하지 않고 양식에 이벤트 위임

간단한 작업으로 두 개의 별도 클래스를 유지해야했습니다. 하나는 프로젝트의 양식과 하나는 어셈블리에 보관해야했습니다. 이것은 분명히 잘못된 길입니다.

내가 뭘 하려는지 알지만 100 % 확실하지는 않습니다. 어떻게해야할지 모르겠습니다.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    Me.Width = 1500 
    Dim panel As New Panel 
    panel.Location = New Point(0, 0) 
    panel.Size = New Size(1000, 200) 
    panel.BackColor = Color.Yellow 
    Me.Controls.Add(panel) 
    Dim factory As New DrawFactory 
    factory.DrawPanel(panel, 5) 
End Sub 

위는 클래스 라이브러리에 다음 코드를 별도의 프로젝트에 있습니다

Public Class DrawFactory 
Private xOffset As Integer = 0 
Private Const widthConst As Integer = 50 
Public Sub DrawPanel(ByRef panel As Panel, ByVal drawPanels As Integer) 
    Application.DoEvents() 
    For i As Integer = 0 To drawPanels 
     Dim childPanel As New Panel 
     childPanel.Location = New Point(xOffset, 0) 
     childPanel.Size = New Size(widthConst, panel.Height) 
     If i < 1 Then 
      childPanel.BackColor = Color.Blue 
     Else 
      childPanel.BackColor = Color.Pink 
     End If 
     xOffset = xOffset + widthConst 
     ''want to add a handler here to open say form5 which is unknown and undefined in the scope of this class 
     panel.Controls.Add(childPanel) 
    Next 
End Sub 
End class 

이 내 실제 코드는 아니지만 내가 '문제의 JIST를 묘사 내가 직면 한 C#이나 VB.NET에서는 답을 신경 쓸 필요가 없다.

+0

문제를 보여주는 간단한 가상의 예제를 작성하십시오. –

+0

@SteveDog 요청한대로 샘플을 추가했습니다. – Tyson

+0

양식에있는 이벤트 처리기를 childPanels의 이벤트에 추가하려고합니까? 그렇다면 어떤 사건입니까? –

답변

1

순환 참조는 .NET에서 기술적으로 문제가되지 않습니다. COM은 참조 계산을 사용하여 개체를 파괴해야하는지 결정하기 때문에 COM의 문제였습니다. 서로 참조하는 두 개의 객체가있는 경우 순환 참조가 객체 참조 횟수를 0으로 만들지 않으므로 절대로 파괴되지 않습니다 (메모리 누수가 발생 함). 그러나 .NET에서 CLR은 참조 카운팅 대신 가비지 수집을 사용합니다. 가비지 수집기는 모든 객체를 주기적으로 검색하여 응용 프로그램에서 더 이상 참조하지 않는 객체를 찾습니다. 그런 다음 발견 된 모든 죽은 물건을 파괴합니다. 가비지 컬렉터는 서로 참조 만되고 둘째는 둘 다 죽은 두 개 이상의 객체가 있다는 것을 알기에 충분히 똑똑합니다. 따라서 .NET 관리 코드에서 순환 참조는 더 이상 메모리 누수를 일으키지 않으므로 더 이상 피할 필요가 없습니다.

그러나 예, 이벤트 처리기 메서드를 다른 프로젝트의 DrawFactory 클래스에 대한 대리자로 전달할 수 있습니다. 그런 다음 DrawFactory 클래스는 원하는 모든 이벤트에 해당 이벤트 처리기를 추가 할 수 있습니다. 예를 들어 :

Public Sub DrawPanel(ByVal panel As Panel, ByVal drawPanels As Integer, ByVal handler As EventHandler) 
    For i As Integer = 0 To drawPanels 
     Dim childPanel As New Panel 
     '... 
     AddHandler panel.Click, handler 
     panel.Controls.Add(childPanel) 
    Next 
End Sub 

그런 다음 양식에, 당신은 같은 이벤트 핸들러의 서명과 일치하는 방법 필요한 것 :

Private Sub Panel_Click(ByVal sender As Object, ByVal e As EventArgs) 
    Form2.Show() 
End Sub 

을 그리고 당신은 다음과 같이 공장을 호출 할 수 있습니다

factory.DrawPanel(panel, 5, New EventHandler(AddressOf Panel_Click)) 
+0

그게 다, 고마워! – Tyson

0

네, 그렇게 할 수 있다고 생각합니다. 클릭 이벤트 서명은 다음과 같습니다

private void ButtonOkClicked(object sender, RoutedEventArgs e) 
{ 

} 

귀하의 클래스 팩토리 작성 방법은 그래서, 액션에 걸릴 수 :

void Create(Action<object, RoutedEventArgs> clickAction) 
{ 
    var btn = new Button(); 
    btn.OnClick += clickAction; 
} 

을 난이, 그렇지 않은 경우 알려 주시기 바랍니다 도움이되기를 바랍니다.

+0

이것이 도움이된다면 샘플을 추가했습니다. WinForms를 사용하고 있습니다. 가져 오기/참조가 누락되지 않으면 IntelliSense에서 "RoutedEventArgs"를 감지하지 못했습니다. 너는 내 문제를 올바르게 이해했다고 믿지만. – Tyson

+0

죄송합니다. 저는 WPF를 추측하고있었습니다. 당신이 문제를 해결해 주어서 다행입니다. – Dave

관련 문제