2013-10-02 58 views
4

我一直在使用DockManagerLayoutRootLayoutAnchorablePaneLayoutDocumentPane如何在關閉標籤後從DockManager中刪除LogicalChildren?

<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,該ContentPresenterUserControl是走進LayoutDocument當我關閉窗口永遠不會被取出,並保持建立越來越多的LogicalChildren直到它開始減慢應用程序。

當我檢測到ChildrenCollectionChanged時,如何刪除與LayoutDocument關聯的ContentPresenterUserControl

編輯1:好的,那麼LogicalChildrenSystem.Linq.Enumerable.WhereSelectListIterator<System.WeakReference,object>,所以我將無法從該列表中刪除任何東西(也只擁有get,並沒有set)。

LayoutDocumentPane.RemoveChild()方法不會對DockingManager.LogicalChildren做任何事情,所以我不知道LogicalChildren是從哪裏抽取迭代日期。

編輯2:所以,我試着添加一個事件到DocumentClosing事件處理程序的DockManager,它似乎仍然沒有從DockManager中刪除未使用的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(); 
    } 
} 

編輯3:看DocumentClosed後剩下的LayoutDocumentPane不作任何修改(而不是DocumentClosing)後,似乎用戶控件從LayoutDocumentPane刪除,但不是從LogicalChildren依然。

+0

你使用的是什麼版本的avalondock? – Jehof

+0

我以前也有過。我自己的解決方法是把AnchorablePane(加上Anchorable中的其他任何東西)和使用'LayoutDocumentPane'作爲工廠站點。我也像你一樣吸引了閉幕式。 –

+0

@Jehof我正在使用v2.0.2000 –

回答

0

由於您處於XceedAvalonDock世界而不是標準的Microsoft控件,因此很難正確理解您的問題。我想我們這裏只有很少人知道xceed的控制細節。此外,我建議你在xceeds論壇發佈這個。

不過我想提幾件適用於每個wpf control的東西,這可能會幫助您解決問題。

無論何時您使用Panel,Pane或任何UIElement進行WPF佈局,最終都會在某些時候向可視和邏輯樹添加/刪除子項。

因此,我建議你去看看下面的鏈接:

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有從「微軟」 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

希望你讓我知道,如果這是無論如何對您有所幫助或其他人在這個誰可能絆倒。如果我完全不理解你的問題,只是讓我知道,我會刪除這篇文章。

+0

感謝您的努力,但這些都不是一種選擇,如果我想使用'FrameworkElement.RemoveLogicalChild',則必須編寫自己的自定義類,因爲它是一個內部函數。 –

+0

那麼這些是wpf中唯一可用來移除孩子的方法。這是不可能的,你不能使用任何這些。是的,刪除邏輯子方法只能在受保護範圍內執行,因此邏輯子進程屬性也可以被覆蓋。你確定你做的一切正確嗎?你確定孩子被困在邏輯樹中嗎? –

+0

你嘗試過窺探邏輯樹嗎?查看codeplex.com上提供的Tool Snoop或類似的東西... –