C# 我什么时候可以处理 IDisposable WPF 控件,例如 WindowsFormsHost?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/254271/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:06:46  来源:igfitidea点击:

When can I dispose an IDisposable WPF control e.g. WindowsFormsHost?

c#.netwpfidisposable

提问by morechilli

The WPF control WindowsFormsHost inherits from IDisposable.

WPF 控件 WindowsFormsHost 继承自 IDisposable。

If I have a complex WPF visual tree containing some of the above controls what event or method can I use to call IDispose during shutdown?

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

采纳答案by morechilli

Building from Todd's answer I came up with this generic solution for any WPF control that is hosted by a Window and want's to guarantee disposal when that window is closed.

根据 Todd 的回答,我为由 Window 托管的任何 WPF 控件提出了这个通用解决方案,并希望在该窗口关闭时保证处理。

(Obviously if you can avoid inheriting from IDisposable do, but sometimes you just can't)

(显然,如果你可以避免从 IDisposable 继承,但有时你不能)

Dispose is called when the the first parent window in the hierarchy is closed.

当层次结构中的第一个父窗口关闭时调用 Dispose。

(Possible improvement - change the event handling to use the weak pattern)

(可能的改进 - 更改事件处理以使用弱模式)

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

            ...

        }

        ...
    }

回答by Pop Catalin

You don't need to dispose controls when closing a form, the API will do it for you automatically if the control is in the visual tree of the form ( as a child of the form or other control in the form)

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

回答by Todd White

In the case of application shutdown there is nothing you need to do to properly dispose of the WindowsFormsHost. Since it derives from HwndHost disposing is handled when the Dispatcher is shutdown. If you use Reflector you will see that when HwndHost is initialized it creates a WeakEventDispatcherShutdown.

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

If you are using it in a dialog the best I can suggest is to override OnClosed and dispose of your Host then, otherwise the HwndHost will hang around until until the Dispatcher is shutdown.

如果您在对话框中使用它,我建议的最好方法是覆盖 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);
    }
}

A simple way to test when dispose gets called is to derive a custom class from WindowsFormsHost and play around with different situations. Put a break point in dispose and see when it gets called.

测试何时调用 dispose 的一种简单方法是从 WindowsFormsHost 派生自定义类并处理不同的情况。在 dispose 中放置一个断点,看看它何时被调用。

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

回答by Pop Catalin

WPF Controls don't implement the IDisposable interface, because they have nothing to dispose(No handles to clean up, no unmanaged memory to release). All you need to do is make sure that you don't have any references to the controls and the GC will clean them.

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

Therefore WPF employs weak event patternsto ensure that controls can be garbage collected. This is the pattern you need to implement to ensure clean-up, not IDisposable.

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