自定义 RegionAdapter 中的 Prism 区域未显示在 RegionManager 列表中 [英] Prism Regions from Custom RegionAdapter Not Showing in RegionManager List

查看:82
本文介绍了自定义 RegionAdapter 中的 Prism 区域未显示在 RegionManager 列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Prism 6.我有一个用于 (AvalonDock) LayoutDocumentPane 的自定义 RegionAdapter.我是这样使用它的:

I'm using Prism 6. I have a custom RegionAdapter for (AvalonDock) LayoutDocumentPane. I'm using it like this:

<!-- 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}">
...

我的区域适配器:

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 注册它

And of course I register it with the 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 中只有 1 个区域- 测试区域".如果我 registerViewWithRegion 到我的ContentRegion",它会在该区域中放置一个视图实例,即使它没有在区域中列出.

Now, see that in the Bootstrapper.InitializeShell call, and the HelloWorldModule.Initialize call, I only have 1 region in the RegionManager - "TestRegion". If I registerViewWithRegion to my "ContentRegion" it puts an instance of the view in that region even though it's not listed in the Regions.

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

If I attempt to navigate from an ICommand function in my ShellViewModel (on a button click for instance) I can navigate to something in the TestRegion but not the ContentRegion. It seems I cannot navigate to any region created by my custom RegionAdapter. What am I missing?

推荐答案

我在 你的在 GitHub 上发布.

根据控件的创建方式,您可能需要自己通过以下方式在控件上设置 Prism RegionManager:

Depending on how the control is created, you may have to set the Prism RegionManager on the control yourself via something like:

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
}

这篇关于自定义 RegionAdapter 中的 Prism 区域未显示在 RegionManager 列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆