具有基于视图的导航棱镜的复杂场景 - 区域管理器不包含“”区域
Complex scenario with View-Based Navigation Prism - The region manager does not contain the ' ' region
我有一个使用 Prism 的基于视图的导航的复杂场景。我正在尝试做的是在父模块的导航区域中为某些模块定义一个新的 NavigationRegion。
我自己解释一下:
我的解决方案中有以下项目:
- Shell
- Shell.Module1
- Shell.Module2
- Shell.Module3
- Shell.Module3.SubModule1
- Shell.Module3.SubModule2
在 shell 视图中,我定义了 MainNavigationRegion 和 MainContentRegion。
模块 1 和 2,将导航项加载到 MainNavigationRegion 并将视图加载到 MainContentRegion。工作正常。
模块 3 带来了复杂性,因为模块 3 本身没有任何功能。这是加载到 MainNavigationRegion 中的 "Shell.Module3" 项目的 NavigationItemView:
<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 中),我正在专门为 Module 3 的子模块定义一个新的 NavigationRegion。
但是,在 Module3.SubModule1 class 的 Initialize() 方法中,出现此错误:'The region manager does not contain the ToolsNavigationRegion region.'
这是方法:
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();
}
}
扩展上面的评论:
区域管理器将通过搜索可视化树来查找标记有区域名称属性的区域。如果在区域管理器进行搜索时某个区域不在可视化树中,则不会创建任何区域。例如,按需创建的弹出窗口 windows 就是这种情况。
在那种情况下,必须在构建弹出窗口时手动分配区域window。
复制自:
可能你需要手动设置区域管理器,在弹出视图的代码后面(构造函数),像这样:
RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );
您必须为托管该区域的内容控件指定一个名称,并以某种方式获取区域管理器 (ServiceLocator.Current.GetInstance<IRegionManager>()
)。
我有一个使用 Prism 的基于视图的导航的复杂场景。我正在尝试做的是在父模块的导航区域中为某些模块定义一个新的 NavigationRegion。
我自己解释一下:
我的解决方案中有以下项目:
- Shell
- Shell.Module1
- Shell.Module2
- Shell.Module3
- Shell.Module3.SubModule1
- Shell.Module3.SubModule2
在 shell 视图中,我定义了 MainNavigationRegion 和 MainContentRegion。 模块 1 和 2,将导航项加载到 MainNavigationRegion 并将视图加载到 MainContentRegion。工作正常。
模块 3 带来了复杂性,因为模块 3 本身没有任何功能。这是加载到 MainNavigationRegion 中的 "Shell.Module3" 项目的 NavigationItemView:
<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 中),我正在专门为 Module 3 的子模块定义一个新的 NavigationRegion。 但是,在 Module3.SubModule1 class 的 Initialize() 方法中,出现此错误:'The region manager does not contain the ToolsNavigationRegion region.' 这是方法:
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();
}
}
扩展上面的评论:
区域管理器将通过搜索可视化树来查找标记有区域名称属性的区域。如果在区域管理器进行搜索时某个区域不在可视化树中,则不会创建任何区域。例如,按需创建的弹出窗口 windows 就是这种情况。
在那种情况下,必须在构建弹出窗口时手动分配区域window。
复制自
可能你需要手动设置区域管理器,在弹出视图的代码后面(构造函数),像这样:
RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );
您必须为托管该区域的内容控件指定一个名称,并以某种方式获取区域管理器 (ServiceLocator.Current.GetInstance<IRegionManager>()
)。