c# - 关闭选项卡后如何从 DockManager 中删除 LogicalChildren?

标签 c# wpf avalondock

我一直在使用 DockManagerLayoutRoot , 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和我的 UserControl进入了LayoutDocument当我关闭窗口时永远不会被删除,并且会越来越多 LogicalChildren直到它开始减慢应用程序。

当我检测到 ChildrenCollectionChanged 时,我该怎么做? , 删除 ContentPresenterUserControl与那个相关的 LayoutDocument

编辑 1:好的,所以 LogicalChildrenSystem.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 中的剩余内容后在DocumentClosed之后没有任何修改(而不是 DocumentClosing ),似乎用户控件已从 LayoutDocumentPane 中删除, 但不是来自 LogicalChildren仍然。

最佳答案

很难正确理解您的问题,因为您处于 XceedAvalonDock 世界中,而不是标准的 Microsoft 控件。我猜我们这里只有少数人详细了解 xceed 的控件。此外,我建议您将其发布到 xceeds 论坛上。

我仍然想向您提及一些适用于每个 wpf 控件 的内容,它们可能会帮助您解决问题。

每当您在 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

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

关于c# - 关闭选项卡后如何从 DockManager 中删除 LogicalChildren?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19140806/

相关文章:

c# - 使用 XMLReader 解析不良的结构化文件

c# - 返回被 UPDATE TOP 1 修改的记录

c# - Popup 中的 UI 虚拟化

mvvm - 使用 AvalonDock 将实例化的 ViewModel 注入(inject)到 View 中

c# - 如何在 AvalonDock 2 中的文档选项卡之间切换

wpf - DateTimePicker 设置日历和时间文化

C# 在 Swift 中使用等效语句

c# - 检查 List<List<string>> 是否包含字符串

wpf - 无法在 Windows 8(WPF、.NET 4.0)下横向打印文档

WPF:缩放用户控件动画