基于视图的导航棱镜的复杂场景-区域管理器不包含''区域

时间:2018-11-03 16:18:51

标签: mvvm navigation prism region

我有一个使用Prism的基于视图的导航的复杂场景。我想做的是在父模块的navitagion区域中为某些模块定义一个新的NavigationRegion。

我会自我解释:

我的解决方案中包含以下项目:

  • 壳牌
  • Shell.Module1
  • Shell.Module2
  • Shell.Module3
  • Shell.Module3.SubModule1
  • Shell.Module3.SubModule2

在外壳视图中,我定义了MainNavigationRegion和MainContentRegion。 模块1和2,将导航项加载到MainNavigationRegion中,将视图加载到MainContentRegion中。很好。

Module3带来了复杂性,因为Module 3本身没有功能。这是“ Shell.Module3”项目的以下NavigationItemView,已加载到MainNavigationRegion中:

<Grid HorizontalAlignment="Center">
    <materialDesign:PopupBox x:Name="NavigateToToolsRadioButton" 
    AutomationProperties.AutomationId="ToolsRadioButton" PopupMode="Click" 
    StaysOpen="False" UseLayoutRounding="False" 
    Style="{StaticResource MaterialDesignMultiFloatingActionAccentPopupBox}"  
    PlacementMode="RightAndAlignMiddles">
        <StackPanel Orientation="Horizontal" x:Name="NavigationItemsControl" 
            prism:RegionManager.RegionName="ToolsNavigationRegion">                
        </StackPanel>
    </materialDesign:PopupBox>
</Grid>

在Module3的NavigationItemView中(已将其加载到MainNavigationRegion中),我正在为模块3的子模块专门定义一个新的NavigationRegion。 但是,在Module3.SubModule1类的Initialize()方法中,出现以下错误:“区域管理器不包含ToolsNavigationRegion区域。” 这是方法:

public void Initialize()
{
    var navitagionView = Container.Resolve<EarnedValueMethodNavigationItemView>();
    RegionManager.Regions[RegionNames.ToolsNavigationRegion].Add(navitagionView);
    var mainView = Container.Resolve<EarnedValueMethodView>();
    RegionManager.Regions[RegionNames.MainContentRegion].Add(mainView);
}

如果我调试RegionManager属性,则会看到ToolsNavigationRegion不存在。

如果我更改此行:

RegionManager.Regions[RegionNames.ToolsNavigationRegion].Add(navitagionView);

另一行:

RegionManager.Regions[RegionNames.MainNavigationRegion].Add(navitagionView);

然后,它工作正常,但显然导航项位于“主导航区域”中,我希望将其放在“父级”模块的“导航区域”项目下。我可能要完成什么?

编辑:

我还如下创建了StackPanel RegionAdapter:

public class StackPanelRegionAdapter : RegionAdapterBase<StackPanel>
{
    public StackPanelRegionAdapter(IRegionBehaviorFactory factory)
        : base(factory)
    {

    }

    protected override void Adapt(IRegion region, StackPanel regionTarget)
    {
        region.Views.CollectionChanged += (s, e) =>
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (FrameworkElement element in e.NewItems)
                {
                    regionTarget.Children.Add(element);
                }
            }

            //implement remove
        };
    }

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

1 个答案:

答案 0 :(得分:0)

扩展以上评论:

区域管理器将通过搜索可视树找到标记有区域名称属性的区域。如果在区域管理器进行搜索时某个区域不在可视树中,则不会创建任何区域。例如,按需创建的弹出窗口就是这种情况。

在这种情况下,必须在构造弹出窗口期间手动分配区域。

this answer复制:

可能您需要在(构造函数)后面的弹出视图代码中手动设置区域管理器,如下所示:

RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );

您必须为托管该区域的内容控件分配一个名称,并以某种方式获取区域管理器(ServiceLocator.Current.GetInstance<IRegionManager>())。