2011-02-14 65 views
2

我有一個棱鏡/ WPF/mef解決方案,其中包含一個AvalonDock。我創建了一個RegionAdapterBase<Pane>類,它處理從AvalonDock創建和刪除窗格。棱鏡RegionAdapter - 刪除然後添加視圖

繼承人,我遇到了這個問題:

  1. 我在菜單中單擊一個按鈕和一個視圖註冊到的區域和顯示我的DocumentPane
  2. 我點擊AvalonDock到關閉按鈕關閉選項卡,去除視圖
  3. 我點擊同一菜單按鈕,重新添加
  4. 我收到的錯誤:

"Specified element is already the logical child of another element. Disconnect it first."

因此......這告訴我,有些東西需要刪除,但我無法弄清楚它在哪裏。繼承人從我RegionAdapter一些代碼:

private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, Pane regionTarget) 
{ 
    if (e.Action == NotifyCollectionChangedAction.Add) 
    { 
     foreach (object item in e.NewItems) 
     { 
      UIElement view = item as UIElement; 

      if (view is ITabViewInfo) 
      { 
       if (view != null) 
       { 
        DockableContent newContentPane = new DockableContent() 
        { 
         Content = item, 
         Title = ((ITabViewInfo)view).TabViewTitle, 
         Icon = new Image() 
         { 
          Source = new BitmapImage(((ITabViewInfo)view).TabViewIcon) 
         }.Source, 
         IsCloseable = ((ITabViewInfo)view).IsCloseable, 
         HideOnClose = ((ITabViewInfo)view).IsHideOnClose 
        }; 

        newContentPane.Closed += (contentPaneSender, args) => 
        { 
         Debug.WriteLine("Removing view from region", "Prism"); 
         region.Remove(item); 
        }; 

        regionTarget.Items.Add(newContentPane); 
        newContentPane.Activate(); 
       } 
      } 
     } 
    } else if (e.Action == NotifyCollectionChangedAction.Remove) { 
      regionTarget.Items.Clear(); 
    } 
    } 

從我的調試線路,DocumentPane和區域的觀點是否正確被摧毀...當我點擊添加回項目的看法,我就得到了上面的錯誤消息,做這行:

Content = item, 

繼承人從我的模塊,當按下菜單按鈕運行的代碼:

if (_regionManager.Regions["MainRegion"].Views.Any(m => m.GetType() == typeof(Views.ClassicFrontierView))) 
    { 
     Debug.WriteLine(_regionManager.Regions["MainRegion"].Views.Count()); 
    } 
    else 
    { 
     Debug.WriteLine("Adding view to region", "Prism"); 
     _regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ClassicFrontierView)); 
    } 

任何想法,我缺少的是什麼?

回答

2

,而不是處理Closed事件(可能已經失去了對底層視圖的引用),我處理Closing事件。

然而,這工作,當我試圖重新打開標籤,它顯示相同的實例。閱讀本In Composite WPF (Prism), what is the difference between IRegion.Add and IRegionManager.RegisterViewWithRegion?後,我改變了這一點:

_regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ClassicFrontierView)); 

這樣:

_regionManager.Regions["MainRegion"].Add(new Classic.Views.ClassicFrontierView()); 

我還要做一些研究與棱鏡/ avalondock,以確保不會有內存泄漏,但截至目前它似乎正在工作。

1

您可能還需要將其從 regionTarget中刪除。

您可以使用Snoop查看尚未從Visual Tree中刪除的內容,然後嘗試找到需要從哪個容器中刪除元素。其他可能性是解凍圖標圖像等。

+0

調用region.Remove(item)後,調用Debug.WriteLine(regionTarget.Items.Count);它輸出0,所以我很確定這是照顧。 AvalonDock正在照顧我相信的事情。 – 2011-02-14 15:15:09

2

您是否每次創建新的視圖或試圖顯示現有視圖多次?如果第二個是正確的我會試試這個:

else if (e.Action == NotifyCollectionChangedAction.Remove) { 
    foreach (DockableContent content in regionTarget.Items) 
     content.Content = null; 
    regionTarget.Items.Clear(); 
} 
+0

我每次都創建一個新視圖。 「else if」僅在視圖首先被刪除時執行(然後刪除相關的窗格)...當我單擊窗格中的「X」時,if(帶有Closed事件處理函數)的第一部分將運行,並且它應該從區域中刪除視圖...這是問題發生的位置。 – 2011-02-14 15:39:28