4

我一直在使用DockManagerwithLayoutRoot和.LayoutAnchorablePaneLayoutDocumentPane

<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和我的永远不会被删除,并且越来越多,直到它开始减慢应用程序的速度。UserControlLayoutDocumentLogicalChildren

当我检测到时ChildrenCollectionChanged,我如何删除ContentPresenterUserControl那相关的和LayoutDocument

编辑 1:好的,LogicalChildren所以System.Linq.Enumerable.WhereSelectListIterator<System.WeakReference,object>我将无法从该列表中删除任何内容(它也只有一个get,并且没有set)。

LayoutDocumentPane.RemoveChild()方法对 没有任何作用DockingManager.LogicalChildren,所以我无法弄清楚从哪里LogicalChildren提取迭代日期。

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

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

编辑 3:在查看 未进行任何修改(而不是)之后剩余的内容LayoutDocumentPane后,似乎用户控件已从 中删除,但仍没有从其中删除。DocumentClosedDocumentClosingLayoutDocumentPaneLogicalChildren

4

3 回答 3

0

很难正确理解您的问题,因为您身处世界XceedAvalonDock不是标准的微软控件。我想我们这里只有少数人详细了解 xceed 的控件。此外,我建议您在 xceeds 论坛上发布此内容。

我仍然想向您提及一些适用于所有wpf control可能帮助您解决问题的事情。

每当您在 WPF 中使用Panel,Pane或其他任何方式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

我希望您让我知道这是否对您或可能偶然发现此问题的其他人有所帮助。万一我根本不理解您的问题,请告诉我,我将删除此帖子。

于 2013-10-19T09:54:35.233 回答
0

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

于 2013-10-23T12:18:41.843 回答
0

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

如果它的父级是 LayoutDocumentPane,则通过删除加载 LayoutAnchorablePane 的属性来修复它。

于 2019-05-22T07:57:01.080 回答