使用Prism,如何将作用域RegionManager注入服务?

时间:2016-02-11 13:23:11

标签: c# wpf prism tabcontrol region

我正在开发一个Prism应用程序,它包含一个TabControl,其中包含几个子区域。因此,我根据Brian Lagunas在https://app.pluralsight.com/library/courses/prism-mastering-tabcontrol/找到的PluralSight课程中描述的模式实现了一个自定义RegionBehavior,并注入了上述课程中描述的自定义RegionNavigationContentLoader,以确保我没有例外,并且可以有区域我的TabControl的几个选项卡上的名称相同。

对于那些无法访问PluralSight的人:

我实现了一个监视区域的Views-collection的行为,并且当它发生更改时,检查添加的视图或其DataContext是否实现了特定的接口。如果检测到此接口,则会将作用域RegionManager设置为该接口的属性,因此进入作用域区域的所有视图都可以知道其作用域RegionManager。

但是,我也有一些服务需要这个作用域RegionManager才能导航到我的TabControl中的子区域。

由于我在容器中创建了这个服务,因此它会注入全局RegionManager而不是作用域。

我的问题是:

  1. 是否有任何模式或结构允许将范围内的RegionManagers注入服务?
  2. 如果对1的答案是否定的,那么服务是否应该导航到区域或者这是一个坏主意?
  3. 更新

    下面是我的应用程序的计划结构。我希望它能说明为什么我要从服务中导航到范围区域:

    Application Layout

    应用程序由已提到的TabControl组成,其中每个TabItem包含分析

    分析总是由选定的可视化组成,可以在右上方的框中选择。选择可视化时,它会在服务中激活,主要调用代码生成可视化,检查设置的有效性等。

    然后,可视化应显示在VisualisationRegion中,特定于可视化的设置应显示在SettingsRegion中。

    我的计划是从服务中导航到这两个区域。

    由于无法预先生成可视化(在显示之前必须始终执行检查,因此我无法直接从视图/视图模型导航。即使可能,显示所有可视化类型的视图也不知道作用域RegionManager,因为它是组合视图的一部分(父视图是知道的,当然可以将作用域RegionManager注入其子视图,但在我看来,这就像代码味道)

    这种类型的应用程序可能不适合Prism导航方法,或者您是否知道如何重构我的应用程序以更好地适应Prism?

2 个答案:

答案 0 :(得分:4)

您无法将范围内的区域经理注入您的服务。哎呀,你甚至无法将一个范围区域管理器注入一个Viewmodel,这就是为什么你需要自定义行为来获取它的原因。

  1. 一个选项是将RegionManager属性添加到您的服务,并将该属性设置为VM中的作用域区域管理器实例。
  2. 我不确定我是否会有任何服务导航到范围区域。这似乎对服务承担了太多责任,这可能导致不必要的复杂性。在这种情况下,我希望服务返回我的VM可以响应的结果,以便导航它需要的位置。根据服务需要导航的原因,您可以采用另一种方法来完成同样的事情。
  3. <强>更新 我会将可视化类型作为主选项卡视图的一部分。我不明白为什么这应该是一个单独的地区。现在,您将可以访问作用域区域管理器,现在可以将视图导航到VisualizationRegion。该服务应该不了解区域经理。只需响应可视化类型选择更改,调用所需服务,获取结果并进行相应导航。

答案 1 :(得分:0)

除了Brians的回答,如果您真的需要在ScopedRegionManager上执行逻辑,我会推荐2种方法。

  1. 让您的服务不知道您的RegionManager或导航逻辑。您还可以返回在服务完成其逻辑时要执行的Action或Func。
  2. 当没有需要替换的逻辑(更改实例注册)时,您也可以将您的逻辑放入RegionManager的扩展方法中:
  3. _

       public static IRegionManager NavigateView(this IRegionManager regionManager, string regionName, string view, NavigationParameters parameters = null)
       {
           var navigationUri = new Uri(view, UriKind.Relative);
           regionManager.RequestNavigate(regionName, navigationUri, parameters);
           return regionManager;
        }