Prism RegionAdapter - 删除然后添加视图

时间:2011-02-14 15:05:33

标签: wpf prism regions avalondock regionadapter

我有一个包含AvalonDock的prism / wpf / mef解决方案。我创建了一个RegionAdapterBase<Pane>类来处理从AvalonDock创建和删除窗格。

这是我遇到的问题:

  1. 我单击菜单中的一个按钮,一个视图已注册一个区域并显示在我的DocumentPane
  2. 我单击AvalonDock中的关闭按钮以关闭选项卡并删除视图
  3. 我点击相同的菜单按钮将其重新添加回来
  4. 我收到错误:
  5.   

    “指定元素已经是   另一个元素的逻辑子。   首先断开它。“

    所以...这告诉我,我需要移除一些东西,但我无法弄清楚它在哪里。来自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));
        }
    

    知道我缺少什么吗?

3 个答案:

答案 0 :(得分:2)

每次创建新视图或尝试多次显示现有视图时?如果第二个是正确的,我会尝试这个:

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

答案 1 :(得分: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());

我仍然需要对Prism / avalondock进行一些研究,以确保没有内存泄漏,但截至目前它似乎正在工作。

答案 2 :(得分:1)

您可能还需要将其从regionTarget中删除。

您可以使用Snoop查看尚未从Visual Tree中删除的内容,然后尝试查找从中删除元素所需的容器。其他可能性包括未冻结的图标图像等。