如何在没有内存泄漏的情况下保留选项卡之间的TabControl状态

时间:2018-06-28 22:16:19

标签: c# wpf wpf-controls

我一直在寻找一种在选项卡之间保留TabControl状态的方法。我发现了几种解决方案,其中包括WPF TabControl: Turning Off Tab Virtualization,这很有趣,但是在关闭选项卡时不会卸载选项卡,并且会导致内存泄漏。因为我的标签页包含一个视频脚本播放器,可能需要700MB到4GB的空间,所以完成后将其卸载很重要。

然后有这个解决方案 TabControlBehavior似乎以相同的语法给出了完全相同的结果,但是方式更简单。但是,它也不会卸载选项卡内容。

如何使这两种解决方案(或任何其他解决方案)中的任何一种在没有内存泄漏的情况下工作?我发现还有其他解决方案会导致与ItemTemplate发生冲突,因此我没有对其进行全面研究。

作为附带问题(和临时解决方法),如何访问给定选项卡中包含的控件?假设我有3个带有X的选项卡将其关闭,选择了选项卡1,然后单击第二个选项卡的X,如何访问其中的控件以进行处理?

从引用到选项卡的ViewModel,我都尝试过。

TabItem CurrentTab = Tabs.ItemContainerGenerator.ContainerFromItem(Viewer) as TabItem;
if (CurrentTab != null) {
    VsMediaPlayerHost Player = FindVisualChildByName<VsMediaPlayerHost>(CurrentTab, "PlayerHost");
    Player?.Stop();
}

但是,这会搜索选项卡标题而不是内容。如果该选项卡自动卸载其内容,则不会有问题,但我仍然想知道。

编辑:我正在探索更简单的代码。它实际上是将选项卡头包装在UserControl中,以防止出于某些原因卸载内容。也许我可以撤消该过程?问题是,当在TabControlUcWrapperBehavior_CollectionChanged或TabItem.Unloaded事件中删除某个项目时,TabItem(我无法直接访问但可以使用缓存保留引用)仅包含“ DisconnectedItem”,因此我无法访问其内容来释放它。可以吗?

更新:我做了很多调查。如果我使用常规的TabControl,它将正确释放引用。如果我关闭了虚拟化功能,.NET Memory Profiler会报告存在其他2个类的根对象...并且如果我删除其他2个类,则该类仍会泄漏并且不会被报告。视线。看起来其他两个都是误报。

现在我正在寻找dotMemory。 MediaPlayerWpf是选项卡中尚未卸载的控件。我们看到它保留在_contextStorage中。

enter image description here

0 个答案:

没有答案