如何在关闭选项卡后从DockManager中删除LogicalChildren?

时间:2013-10-02 15:34:01

标签: c# wpf avalondock

我一直在使用DockManager LayoutRootLayoutAnchorablePaneLayoutDocumentPane

<ad:DockingManager x:Name="dockManager" >
  <adLayout:LayoutRoot>
    <adLayout:LayoutPanel x:Name="myLayoutPanel" Orientation="Horizontal">
      <adLayout:LayoutAnchorablePane x:Name="myLayoutAnchorablePane" DockWidth="400"/>
      <adLayout:LayoutDocumentPane x:Name="myDocumentPane" ChildrenCollectionChanged="myDocumentPane_ChildrenCollectionChanged"/>
    </adLayout:LayoutPanel>
  </adLayout:LayoutRoot>
</ad:DockingManager>

但是,我提到的一个问题是,在DockManager.LogicalChildren中,当我关闭窗口时,进入ContentPresenter的{​​{1}}和UserControl永远不会被删除并且不断积累LayoutDocument,直到它开始减慢应用程序的速度。

当我检测到LogicalChildren时,如何移除与ChildrenCollectionChanged相关联的ContentPresenterUserControl

编辑1:好的,LayoutDocumentLogicalChildren,因此我无法从该列表中删除任何内容(也只有System.Linq.Enumerable.WhereSelectListIterator<System.WeakReference,object>,而且get 1}})。

set方法对LayoutDocumentPane.RemoveChild()没有任何作用,因此我无法确定DockingManager.LogicalChildren从中提取迭代日期的位置。

编辑2:所以,我尝试向LogicalChildren的{​​{1}}事件处理程序添加一个事件,它似乎仍然没有从DockManager中删除未使用的DocumentClosing

DockManager

编辑3:在LogicalChildren之后void dockManager_DocumentClosing(object sender, Xceed.Wpf.AvalonDock.DocumentClosingEventArgs e) { UserControl uc = e.Document.Content as UserControl; e.Cancel = true; e.Document.IsActive = false; if(uc != null) { var u = myDocumentPane.Children.Where(a => a.Content.Equals(uc)).FirstOrDefault(); u.IsActive = false; u.Close(); myDocumentPane.Children.Remove(u); myDocumentPane.RemoveChild(u); var oldLogicalParentPaneControl = LogicalTreeHelper.GetParent(u.Content as UIElement) as Xceed.Wpf.AvalonDock.DockingManager; oldLogicalParentPaneControl.Layout.RemoveChild(u); oldLogicalParentPaneControl.Layout.CollectGarbage(); dockManager.UpdateLayout(); } } 未经任何修改(而不是LayoutDocumentPane)查看剩余DocumentClosed内的内容后,似乎已从{{1}中删除了用户控件},但不是来自DocumentClosing

3 个答案:

答案 0 :(得分:0)

由于您处于XceedAvalonDock世界而非标准微软控件,因此很难正确理解您的问题。我想我们这里只有少数人知道xceed的控件细节。我还建议你在xceeds论坛发帖。

我仍然想提及一些适用于每个wpf control可以帮助您解决问题的事情。

每当您在WPF中使用PanelPane或任何UIElement进行布局时,您最终都会在视觉和逻辑树中添加/删除子项。

因此,我建议您查看以下链接:

http://msdn.microsoft.com/en-us/library/ms753391.aspx

这将详细解释wpf树。

另请查看Panel.Children的链接:

http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.internalchildren.aspx

我不知道你的LayoutPanel是否继承自“Microsoft”Panel,但如果是,那么你怎么样尝试这样的事情:

layoutPanel.Children.Remove(..)

Children是一个UIElementCollection,每个UIElementCollection在内部调用Remove()RemoveVisualVisual()和RemoveLogicalChild()方法。

http://msdn.microsoft.com/en-us/library/system.windows.controls.uielementcollection.aspx

最后,我提出了两种替代解决方案。如果上述任何内容都无法帮助您,您只需找到您希望删除的控件的父级FrameworkElement,并使用FrameworkElement.RemoveLogicalChild从逻辑树中删除子级。

检查此链接:

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.removelogicalchild.aspx

第二种替代解决方案是覆盖布局面板的LogicalChildren属性。

此链接向您解释如何: http://msdn.microsoft.com/en-us/library/ms742244.aspx

我希望你告诉我这是否对你或其他可能偶然发现的人有所帮助。如果我根本不理解你的问题,请告诉我,我会删除这篇文章。

答案 1 :(得分:0)

我认为这是一个内存泄漏问题。你是否试图调查内存分析器以了解发生了什么? 另外,我发现这个链接也许是你的情况? http://avalondock.codeplex.com/workitem/16060

答案 2 :(得分:0)

在LayoutDocumentPane上使用DockingManager的序列化时,我遇到了这个问题。从xml加载LayoutAnchorablePane之后,我无法将其关闭。

通过删除加载的LayoutAnchorablePane的属性(如果其父项是LayoutDocumentPane)来解决此问题。