我一直在使用 DockManager
与 LayoutRoot
, LayoutAnchorablePane
和 LayoutDocumentPane
.
<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
时,我该怎么做? , 删除 ContentPresenter
和 UserControl
与那个相关的 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
中的剩余内容后在DocumentClosed
之后没有任何修改(而不是 DocumentClosing
),似乎用户控件已从 LayoutDocumentPane
中删除, 但不是来自 LogicalChildren
仍然。
最佳答案
很难正确理解您的问题,因为您处于 Xceed
和 AvalonDock
世界中,而不是标准的 Microsoft 控件。我猜我们这里只有少数人详细了解 xceed 的控件。此外,我建议您将其发布到 xceeds 论坛上。
我仍然想向您提及一些适用于每个 wpf 控件
的内容,它们可能会帮助您解决问题。
每当您在 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
如果这对您或其他可能偶然发现它的人有帮助,我希望您能告诉我。如果我根本不明白你的问题,请告诉我,我会删除这篇文章。
关于c# - 关闭选项卡后如何从 DockManager 中删除 LogicalChildren?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19140806/