2011-02-14 80 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