Nested Regions

Topics: Prism v4 - WPF 4
Feb 22, 2013 at 5:43 PM
Edited Feb 22, 2013 at 5:45 PM
Hi,
I'm using Prism-Mef, i have RegionB which is nested inside RegionA
When i declare:
 IRegion regionB= regionManager.Regions[RegionNames.RegionB];
i got the exception:
The region manager does not contain the RegionB region.
1-How i can access RegionB to Add view to it, knowing that i will use it as a scoped region.
2-If i have a third level of nesting: for example RegionC which is nested inside RegionB, how can use RegionC to add a View

Thanks in advance.
Developer
Feb 22, 2013 at 6:58 PM
Hi,

Based on your description it seems that the cause of the exception is that you are searching for the RegionB in the main region manager instead of the scoped one: The RegionB is a scoped region inside the ViewA , so it will be register in the scoped region manager of the ViewA and not in the main one. Hence, in order to obtain the RegionB you need to access that region manager (lets call it RegionManagerA .)

As out of the box, Prism does not provide any functionality to access scoped region managers, so you will to implement your custom logic to store and retrieve them in order to use them later. How to implement this functionality will depend of the architecture of your application, its requirements and your personal preferences. For example, if you need to obtain the RegionB inside a controller, when injecting the ViewA and receiving its RegionManagerA you could also store the region manager in the controller (for example using an event) so that later the controller will be able to use it.

As a side note, if for example you need to obtain the RegionManagerA in the ViewModelA in order to inject or navigate to a view in the RegionB , I believe you could find the RegionManagerAwareBehavior I developed for the following blog post interesting:
Although, the behaviors was initially designed for other purposes, it allows a view / view model to find their corresponding view model in the visual tree. Hence, it can be useful to obtain the RegionManagerA inside the ViewModelA .

These same concepts can be also applied for sub-nested regions and views.

I hope this helps,

Damian Cherubini
http://blogs.southworks.net/dcherubini
Feb 22, 2013 at 7:15 PM
Hi Damian,
Thanks for your quick response.
i have the following method in ControllerB in ModuleB which is triggered by EventAggregator
to add ViewB="TestPacksView" in RegionB="TestPackGridRegion" which is nested inside RegionA
that exist in a ViewA in ModuleA.
How exactly i can modify this code to access the nested region "TestPackGridRegion" and add "TestPacksView"
 private void ShowTestPacksGrid(PreCommissioning.Model.Subsystem Subsys)
        {   
            IRegion pipingRegion = regionManager.Regions[RegionNames.TestPackGridRegion];
            
            object existingView = pipingRegion.GetView("TestPacksView");


            if (existingView == null)
            {
                // the view does not exist yet. Create it and push it into the region
                testPacksViewModel.SetSubsystem(Subsys);

                existingView = ServiceLocator.Current.GetInstance<ITestPacksView>();
                pipingRegion.Add(existingView, "TestPacksView",true);
            }
            else
            {
                // The view already exists. Just show it. 
                pipingRegion.Activate(existingView);
            }
            
            
        }

Your help is very much appreciated.
Developer
Feb 26, 2013 at 8:45 PM
Hi,

Based on my understanding, you have to access the RegionManager attached to the ViewA view in order for this code to work. If you know in which region the ViewA is injected, a quick workaround for doing so (although not the best one) could be to obtain the ViewA from that region, then obtain the RegionManager from that view.

Basically, the RegionManagers are stored in their corresponding views as attached properties. Using the GetRegionManager static method of the RegionManager class you can obtain the RegionManager attached to a control. Hence, you could do something like this:
  • Obtain the RegionA from the common RegionManager
  • Obtain the ViewA from the RegionA , for example using the GetView method
  • Obtain the scoped RegionManager from the ViewA using the GetRegionManager method. This RegionManager should contain the TestPackGridRegion .
The rest of the code would be the same, but using the second RegionManager .

I hope this helps,

Damian Cherubini
http://blogs.southworks.net/dcherubini