WPF 控件 WindowsFormsHost 继承自 IDisposable。
如果我有一个包含上述某些控件的复杂 WPF 可视化树,我可以在关机期间使用什么事件或方法来调用 IDispose?
WPF 控件 WindowsFormsHost 继承自 IDisposable。
如果我有一个包含上述某些控件的复杂 WPF 可视化树,我可以在关机期间使用什么事件或方法来调用 IDispose?
在应用程序关闭的情况下,您无需执行任何操作即可正确处理 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);
}
}
根据 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();
};
}
};
...
}
...
}
关闭表单时不需要释放控件,如果控件位于表单的可视树中(作为表单的子项或表单中的其他控件),API 会自动为您处理
WPF 控件不实现 IDisposable 接口,因为它们没有要处理的内容(没有要清理的句柄,没有要释放的非托管内存)。您需要做的就是确保您没有对控件的任何引用,并且 GC 会清理它们。
因此 WPF 使用弱事件模式来确保控件可以被垃圾回收。这是您需要实施以确保清理的模式,而不是 IDisposable。