12

WPF コントロールの WindowsFormsHost は、IDisposable を継承しています。

上記のコントロールのいくつかを含む複雑な WPF ビジュアル ツリーがある場合、シャットダウン中に IDispose を呼び出すためにどのイベントまたはメソッドを使用できますか?

4

4 に答える 4

8

アプリケーションのシャットダウンの場合、WindowsFormsHost を適切に破棄するために必要なことは何もありません。HwndHost から派生しているため、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 からカスタム クラスを派生させ、さまざまな状況で試してみることです。dispose にブレーク ポイントを設定し、いつ呼び出されるかを確認します。

public class CustomWindowsFormsHost : WindowsFormsHost
{
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }
}
于 2008-11-02T23:44:51.267 に答える
4

Todd の回答から構築して、ウィンドウによってホストされ、そのウィンドウが閉じられたときに破棄を保証したい WPF コントロールに対して、この一般的なソリューションを思いつきました。

(明らかに、IDisposable からの継承を回避できる場合はそうしますが、そうでない場合もあります)

Dispose は、階層内の最初の親ウィンドウが閉じられるときに呼び出されます。

(改善の可能性 - イベント処理を変更して弱いパターンを使用する)

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();
                    };
                }
            };

            ...

        }

        ...
    }
于 2008-11-03T12:26:01.497 に答える
-1

WPF コントロールは IDisposable インターフェイスを実装しません。これは、処分するものが何もないためです(クリーンアップするハンドルや解放するアンマネージ メモリがないため)。コントロールへの参照がないことを確認するだけで、GC によってそれらがクリーンアップされます。

そのため、WPF は弱いイベント パターンを使用して、コントロールを確実にガベージ コレクションできるようにします。これは、IDisposable ではなく、確実にクリーンアップするために実装する必要があるパターンです。

于 2008-11-03T23:30:51.093 に答える
-1

フォームを閉じるときにコントロールを破棄する必要はありません。コントロールがフォームのビジュアル ツリーにある場合 (フォームの子またはフォーム内の他のコントロールとして)、API が自動的に破棄します。

于 2008-11-01T00:42:22.387 に答える