12

WPF 控件 WindowsFormsHost 继承自 IDisposable。

如果我有一个包含上述某些控件的复杂 WPF 可视化树,我可以在关机期间使用什么事件或方法来调用 IDispose?

4

4 回答 4

8

在应用程序关闭的情况下,您无需执行任何操作即可正确处理 WindowsFormsHost。因为它派生自 HwndHost,所以 Dispatcher 在 Dispatcher 关闭时处理。如果你使用 Reflector,你会看到当 HwndHost 被初始化时,它会创建一个 WeakEventDispatcherShutdown。

如果您在对话框中使用它,我可以建议的最好方法是覆盖 OnClosed 并处理您的主机,否则 HwndHost 将一直存在,直到 Dispatcher 关闭。

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 的回答,我为由 Window 托管的任何 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

关闭表单时不需要释放控件,如果控件位于表单的可视树中(作为表单的子项或表单中的其他控件),API 会自动为您处理

于 2008-11-01T00:42:22.387 回答
-1

WPF 控件不实现 IDisposable 接口,因为它们没有要处理的内容(没有要清理的句柄,没有要释放的非托管内存)。您需要做的就是确保您没有对控件的任何引用,并且 GC 会清理它们。

因此 WPF 使用弱事件模式来确保控件可以被垃圾回收。这是您需要实施以确保清理的模式,而不是 IDisposable。

于 2008-11-03T23:30:51.093 回答