自定义区域适配器中的棱镜区域未显示在RegionManager列表中

时间:2015-10-21 01:04:54

标签: prism

我使用Prism 6.我有(AvalonDock)RegionAdapter的自定义LayoutDocumentPane。我这样使用它:

<!-- relevant lines from Shell.xaml. These regions are autoWired -->
<ad:LayoutDocumentPaneGroup>
    <ad:LayoutDocumentPane prism:RegionManager.RegionName="{x:Static inf:RegionNames.ContentRegion}">
    </ad:LayoutDocumentPane>
</ad:LayoutDocumentPaneGroup>
...
<ContentControl prism:RegionManager.RegionName={x:Static inf:RegionNames.TestRegion}">
...

My RegionAdapter:

public class AvalonDockLayoutDocumentRegionAdapter : RegionAdapterBase<LayoutDocumentPane>
{
    public AvalonDockLayoutDocumentRegionAdapter(IRegionBehaviorFactory factory) : base(factory)
    {
    }

    protected override void Adapt(IRegion region, LayoutDocumentPane regionTarget)
    {
        region.Views.CollectionChanged += (sender, e) =>
        {
            OnRegionViewsCollectionChanged(sender, e, region, regionTarget);
        };
    }

    private void OnRegionViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, LayoutDocumentPane regionTarget)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (var item in e.NewItems)
            {
                var view = item as FrameworkElement;
                if (view != null)
                {
                    var layoutDocument = new LayoutDocument();
                    layoutDocument.Content = view;

                    var vm = view.DataContext as ILayoutPaneAware;
                    if (vm != null)
                    {
                        //todo bind to vm.Title instead
                        layoutDocument.Title = vm.Title;
                    }

                    regionTarget.Children.Add(layoutDocument);
                    layoutDocument.IsActive = true;
                }
            }
        } else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (var item in e.OldItems)
            {
                var frameworkElement = item as FrameworkElement;
                var childToRemove = frameworkElement.Parent as ILayoutElement;

                regionTarget.RemoveChild(childToRemove);
            }
        }
    }

    protected override IRegion CreateRegion()
    {
        return new Region();
    }
}

当然我用Bootstrapper注册它

    ...
    protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
    {
        var mappings = base.ConfigureRegionAdapterMappings();

        mappings.RegisterMapping(typeof(LayoutDocumentPane), Container.Resolve<AvalonDockLayoutDocumentRegionAdapter>());

        return mappings;
    }

    protected override void InitializeShell()
    {
        var regionManager = RegionManager.GetRegionManager(Shell);
        // Here, regionManager.Regions only contains 1 Region - "TestRegion".
        // Where is my region from the custom RegionAdapter?

        Application.Current.MainWindow.Show();
    }

    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<Shell>();
    }

    protected override void ConfigureModuleCatalog()
    {
        ModuleCatalog moduleCatalog = (ModuleCatalog)ModuleCatalog;
        moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
    }
    ...

我的模块

...
    public HelloWorldModule(IRegionManager regionManager, IUnityContainer container)
    {
        _regionManager = regionManager;
        _container = container;
    }

    public void Initialize()
    {
        _container.RegisterTypeForNavigation<HelloWorldView>("HelloWorldView");

        // When uncommented, this next line works even though the region
        //  with this name doesn't appear in the list of regions in _regionManager
        //_regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(HelloWorldView));
    }
...

现在,请参阅Bootstrapper.InitializeShell来电和HelloWorldModule.Initialize来电,RegionManager - &#34; TestRegion&#34;中只有1个区域。如果我registerViewWithRegion到我的&#34; ContentRegion&#34;它在该区域中放置了一个视图实例,即使它没有在区域中列出。

如果我尝试从ShellViewModel中的ICommand函数导航(例如按下按钮),我可以导航到TestRegion但不是ContentRegion中的内容。我似乎无法导航到我的自定义RegionAdapter创建的任何区域。我错过了什么?

2 个答案:

答案 0 :(得分:0)

下面的代码很可能会导致问题。

protected override IRegion CreateRegion() { return new Region(); }

尝试更改以返回可以托管多个有效视图的区域

protected override IRegion CreateRegion()
{
    return new AllActiveRegion();
}

答案 1 :(得分:0)

我在GitHub上的your issue中看到了这一点。

根据控件的创建方式,您可能需要通过以下方式自行设置控件上的棱镜RegionManager

private readonly IRegionManager _regionManager;

public AvalonDockLayoutDocumentRegionAdapter( 
    IRegionBehaviorFactory regionBehaviorFactory, 
    IRegionManager regionManager 
    ) : base( regionBehaviorFactory ) {
    this._regionManager = regionManager;
}

protected override void Adapt( IRegion region, LayoutDocumentPane target ) {
    RegionManager.SetRegionManager( target, this._regionManager );
    // continue with Adapt
}