【问题标题】:Prism Regions from Custom RegionAdapter Not Showing in RegionManager List来自自定义 RegionAdapter 的 Prism 区域未显示在 RegionManager 列表中
【发布时间】:2018-02-06 06:24:23
【问题描述】:

我正在使用 Prism 6。我有一个自定义 RegionAdapter 用于 (AvalonDock) 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}">
...

我的 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();
    }
}

当然我用引导程序注册它

    ...
    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 个区域-“TestRegion”。如果我 registerViewWithRegion 到我的“ContentRegion”,它会在该区域中放置一个视图实例,即使它没有在区域中列出。

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

【问题讨论】:

    标签: prism


    【解决方案1】:

    很可能是您下面的代码导致了问题。

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

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

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

    【讨论】:

      【解决方案2】:

      我在 GitHub 上的 your issue 看到了这个。

      根据控件的创建方式,您可能需要通过以下方式自行在控件上设置 Prism 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
      }
      

      【讨论】:

      • 我遇到了类似的问题,但主要问题是 Adapt 方法从未被调用过,因此没有任何区别。
      猜你喜欢
      • 2016-07-29
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      相关资源
      最近更新 更多