如何反初始化一个FrameworkElement?

3
我们有一个从FrameworkElement派生的类,但这个类不在我们的控制之下。该类在OnInitialize方法中注册事件处理程序。
由于FrameworkElement没有提供OnInitialize的对应方法,因此要正确清除此类的模式是什么?
它仍然保持根源状态,因为没有任何部分删除EventHandler,导致泄漏。
3个回答

3
“Deinitializing”并不存在。当对象的完全初始化依赖于在构造函数期间不可用的数据时,会使用初始化方法。在这些情况下,构造分为两个阶段:第一步在无参数构造函数中执行,第二步在初始化方法(例如OnInitialize)中执行,在外部数据变得可用之后进行。
你所描述的是对象处理,它是通过调用对象的Dispose方法实现的。一个良好编写的类应清理其数据,释放任何外部资源,还需释放任何事件处理程序。
通常,可视元素的生命周期还有另一步骤,在OnLoad/OnUnload方法中处理。当将元素实际放置在XAML视图中并连接到其他UI元素时,发生加载步骤。事件处理程序应在OnLoad方法中注册,并在OnUnload方法中移除。
如果元素没有Dispose方法,则可以触发Unload事件以强制清除,尽管这有点像hack。
control.RaiseEvent(new RoutedEventArgs(FrameworkElement.UloadedEvent))

涉及的类位于AvalonDock库中。没有概念论文可以证明为什么这些事件没有被清理。 - Portikus
1
一个停靠窗口应该只在每个表单中创建一次。考虑到停靠窗口用于应用程序的主窗体,这应该只在应用程序的生命周期中发生一次。您是否在运行时创建了很多表单?您会处理这些表单、重复使用它们还是让它们被垃圾回收? - Panagiotis Kanavos
我们正在按需创建ViewModels(以及它们的视图作为Anchorables)。就像Visual Studio不会在启动时创建所有可能的窗口一样。LayoutContent具有Closing事件和受保护的OnClosing以支持此操作。分析显示,关闭窗口会正确处理我们的ViewModel,但是随后的隐式“释放”LayoutDocumentPaneGroupControl失败了,因为它仍然具有活动的事件处理程序。没有迹象表明不支持关闭。 - Portikus

2

0

使用 Dispatcher.ShutdownStarted 事件。

将以下代码添加到构造函数中:

Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;

并将你的清理代码添加到这个方法中:

private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
{
    Stop();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接