4

I am developing a Prism application and it contains a TabControl which contains several child regions. Therefore I implemented a custom RegionBehavior, according to the pattern described by Brian Lagunas in his PluralSight course found at https://app.pluralsight.com/library/courses/prism-mastering-tabcontrol/ and injected a custom RegionNavigationContentLoader also described in the aforementioned course, to make sure I get no exceptions and can have regions of the same name on several tabs of my TabControl.

For those who have no access to PluralSight:

I implemented a behavior that monitors the Views-collection of a region, and, when it changes, checks, whether the added view or its DataContext implements a specific interface. If this interface is detected, it sets the scoped RegionManager to a property of that interface, so all views that go into a scoped region can be aware of their scoped RegionManager.

However, I also have some services that require this scoped RegionManager in order to navigate to a child region inside my TabControl.

Since I am creating this service in my container, it gets the global RegionManager injected instead of the scoped one.

My questions are:

  1. Are there any patterns or structures that allow for injecting scoped RegionManagers into services?
  2. If the answer to 1 is no, should services navigate to regions anyway or is this a bad idea?

Update

Below you find the planned structure of my application. I hope it makes clear why I want to navigate to a scoped region from within a service:

Application Layout

The application consists of a TabControl as already mentioned, where each of the TabItems contains an analysis.

An analyis always consists of a selected visualisation which can be selected in the upper right box. When a visualisation is selected it gets activated in a service, which mainly calls code to generate the visualisation, checks for validity of settings etc.

Then the visualisation should be shown in the VisualisationRegion and the visualisation-specific settings should be shown in the SettingsRegion.

My plan was to navigate to those two regions from within the service.

Since the visualisations can not be generated beforehand (there are checks that must always be executed prior display I can not navigate directly from the view/viewmodel. Even if that was possible the view displaying all the visualisation types is not aware of the scoped RegionManager, since it is part of a composed view (the parent view is aware and could of course inject the scoped RegionManager into its child view, but that seems to me like a code smell)

Is this type of application maybe not suitable for Prisms navigation approach or do you have an idea how I could restructure my application to better fit with Prism?

Taterhead
  • 5,763
  • 4
  • 31
  • 40
David
  • 625
  • 6
  • 14

2 Answers2

4

You're not going to be able to inject a scoped region manager into your service. Heck, you can't even inject a scoped region manager into a Viewmodel which is why you needed the custom behavior to get it in the first place.

  1. One option is to add a RegionManager property to your service and set that property to the scoped region manager instance in your VM.
  2. I'm not sure I would have any service navigating into scoped regions. That seems to place too much responsibility into a service, which can cause un-needed complexity. In this case, I would expect the service to return a result in which my VM can respond to in order to navigate where it needs to be. Depending on why the service needs to navigate, you may be able to take another approach to accomplish the same thing.

Update: I would make the visualization types part of the main tabbed view. I don't see any reason why that should be a separate region. This will now give you access to the scoped region manager and you can now navigate views into the VisualizationRegion. The service should have no knowledge of the region manager. Simply respond to the visualization type selection changes, call the service you need, get the result, and navigate accordingly.

  • Thanks for your reply. I already suspected that I can not inject a SRM into my service, but I was hoping for a pattern like the IRegionAware to achive this.I extended my question to make my requirements (hopefully) a bit clearer. Maybe you have an idea? – David Feb 12 '16 at 09:52
0

In addition to Brians answer I would recommend 2 ways if you really need to execute a logic on your ScopedRegionManager.

  1. Keep your Service unaware of your RegionManager or Navigation-logic. You can also return an Action or Func to be executed when the service completes its logic.
  2. When there is no logic that need to be replaced (change instance registration) you could also put your logic into an extension method of RegionManager:

_

   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;
    }
JanDotNet
  • 3,746
  • 21
  • 30
Johannes Wanzek
  • 2,825
  • 2
  • 29
  • 47