2008-10-31 2 views
11

WPF 컨트롤 WindowsFormsHost는 IDisposable에서 상속받습니다.언제 IDisposable WPF 컨트롤을 처리 할 수 ​​있습니까? WindowsFormsHost?

위의 컨트롤 중 일부가 포함 된 복잡한 WPF 시각적 트리가있는 경우 종료 중에 IDispose를 호출하는 데 사용할 수있는 이벤트 나 메서드는 무엇입니까?

+1

'종료 중'이라고 말하면 앱이 종료 된 것입니까? 컨트롤이 더 이상 보이지 않습니까? 대화 상자가 닫혀 있습니까? –

+0

여기서 애플리케이션 종료를 의미하지만 대화 닫기 케이스에 관심이 있습니다. – morechilli

답변

4

건물 나는 창에 의해 호스팅 및 해당 창을 닫을 때의 폐기를 보장하고자하는 모든 WPF 컨트롤이 일반적인 솔루션을 함께했다.

(물론 당신이는 IDisposable에서 상속 피할 수있다, 그러나 때때로 당신은 단지 수없는 경우) 계층 구조에서 첫 번째 부모 창을 닫을 때

폐기가 호출됩니다.

(가능한 개선 - 약한 패턴을 사용하여 이벤트 처리 변경)가 정리 (없음 핸들을 버리지 게 없다 때문에,

public partial class MyCustomControl : IDisposable 
    { 

     public MyCustomControl() { 
      InitializeComponent(); 

      Loaded += delegate(object sender, RoutedEventArgs e) { 
       System.Windows.Window parent_window = Window.GetWindow(this); 
       if (parent_window != null) { 
        parent_window.Closed += delegate(object sender2, EventArgs e2) { 
         Dispose(); 
        }; 
       } 
      }; 

      ... 

     } 

     ... 
    } 
+0

질문 : 처분 방법에서 무엇을합니까? –

+0

은 컨트롤에 따라 다릅니다. 일반적으로 아무 것도 없지만 불행히도 특별한 경우가 있습니다. 답변에 대한 내 의견을 참조하십시오. – morechilli

+2

Windows Forms 앱 내에서 WPF를 호스팅하는 사람들에게는 실패합니다. 또한 기본 폼에 대한 연결된 WinForms 닫기 이벤트에 선택적으로 연결하는 더 많은 호환 방법이 있지만 그렇게하면 널리 재사용 가능한 WPF 컨트롤 라이브러리로는 충분하지 않습니다. 또한 메인 윈도우가 닫혀있을 때만 정리하는 것은 대부분의 개발자들이 원하는 것은 아닙니다. 대신 트리의 첫 번째 창/페이지가 범위를 벗어 났을 때 (반드시 닫을 필요는 없음) 정리 작업을 수행하는 것이 더 바람직합니다. – jpierson

-1

양식을 닫을 때 컨트롤을 처리 할 필요가 없습니다. 컨트롤이 양식의 시각적 트리 (양식의 다른 컨트롤 또는 폼의 자식)에 있으면 API가 자동으로 처리합니다.

+0

내 WFH는 주 wpf 창을 포함하는 트리의 다른 WPF 컨트롤의 하위 노드입니다. WFH는 결코 호출되지 않습니다. – morechilli

+0

주 wpf 창에서 Dispose가 호출되면 모든 자식이 삭제됩니다 (기타 등등). 귀하의 WFH 통제는 귀하의 추가 작업없이 그 당시 처분되어야합니다. –

+4

wpf 응용 프로그램 클래스 나 wpf 창 클래스가 IDisposable에서 상속받지 못한다면 - wpf는 winforms를 가져올 때까지 처분 할 필요가 없다고 생각합니다. – morechilli

8

응용 프로그램 종료의 경우 WindowsFormsHost를 올바르게 처리하기 위해 수행 할 필요가 없습니다. HwndHost에서 파생되므로 Dispatcher는 Dispatcher가 종료 될 때 처리됩니다. Reflector를 사용하면 HwndHost가 초기화 될 때 WeakEventDispatcherShutdown이 생성됩니다.

대화 상자에서 사용하는 경우 가장 좋은 방법은 OnClosed를 무시하고 호스트를 삭제하는 것입니다. 그렇지 않으면 Dispatcher가 종료 될 때까지 HwndHost가 중단됩니다.

public partial class Dialog : Window 
{ 
    public Dialog() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnClosed(EventArgs e) 
    { 
     if (host != null) 
      host.Dispose(); 

     base.OnClosed(e); 
    } 
} 

dispose가 호출 될 때 테스트하는 간단한 방법은 WindowsFormsHost에서 사용자 지정 클래스를 파생시키고 다양한 상황을 처리하는 것입니다. 폐기 시점을 정하고 언제 호출되는지 확인하십시오. 토드의 대답에서

public class CustomWindowsFormsHost : WindowsFormsHost 
{ 
    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
    } 
} 
+0

Thx는 좋은 소리입니다. 앱을 사용하여 windowsform을 제어합니다.평생 나는 hwdhost에 의존하여 디스패처 종료 이벤트에 후킹 할 수 있습니다. 대화 상자에서 대화창의 onclosed 이벤트에 대한 비슷한 훅을 쓸 수 있었고이 두 패턴을 일반 IDisposable 컨트롤에 복사 할 수있었습니다. – morechilli

0

WPF 컨트롤이는 IDisposable 인터페이스를 구현하지 않습니다를, 해제 할 관리되지 않는 메모리 없음). 컨트롤에 대한 참조가 없으면 GC가 컨트롤을 참조해야합니다.

따라서 WPF는 컨트롤이 가비지 수집 될 수 있도록 weak event patterns을 사용합니다. 이것은 IDisposable이 아닌 정리를 위해 구현해야하는 패턴입니다.

+1

일반적으로 WindowsFormsHost는 WPF 컨트롤이며 IDisposable을 구현하지만 예를 들어 예외가 있지만 올바른 것입니다. winforms 컨트롤을 호스트하는대로 처리 할 hwnd가 있습니다. – morechilli

+0

처리 할 항목이 있으면 IDisposable을 구현하십시오. 그렇지 않은 경우 IDisposable을 구현하십시오. 그러나 그렇게 할 때까지는 구현하지 마십시오. –

+0

약한 이벤트 패턴은 기존 컨트롤을 스왑 아웃하고 해당 컨트롤의 모든 이벤트가 언 Hook되어 처리 이벤트를 중지하지 않도록하려는 경우에도 여전히 문제가 될 수 있습니다. 우리의 실험에서는 이러한 사건들이 계속해서 발생하는 것으로 보인다. Dispose 호출은 WinForms에서도이 이벤트 정리 목적을 제공하는 데 사용됩니다. – jpierson

관련 문제