navigationprismregions

Prism - ViewModel-First, Navigation API, with Scoped Regions


Found a few examples which attempted to couple scope region functionality with Prism's Navigation API, but I don't quite understand how I can put this together using a viewmodel-first approach with implicit datatemplates - each wrapping a UserControl.

Some of my UserControls are wrapped within multiple DataTemplates. These UserControls specify their own regions.

My main shortcoming, is my inability to grasp how it's possible to grab a reference to the Local RegionManager during a Navigation request. How can I notify Prism to create the scoped region, if necessary, and Import the local RegionManager instance inside the Constructor of a child ViewModel which initiates a Navigation request?

Any help?


Solution

  • Based on my understanding, Navigation with ScopedRegions would not be a straight forward feature of Prism. There are some workarounds posted however, in order to accomplish it in a quite simple way.

    You can look at the following post and discussion thread for handling ScopeRegionManagers across Navigation:

    Basically, Agustin Adami's proposal would be to obtain the scoped RegionManager from the Region.Add() method, through the NavigationResult passed in the navigation callback from the RequestNavigate() method.

    The Navigation call then would look as follows:

    this.regionManager.RequestNavigate( "MainRegion",
    new Uri("HelloWorldView?createRegionManagerScope=true", UriKind.Relative),
    (result) =>
    {
        var myRegionManager = result.ExtractRegionManager();
        myRegionManager.RequestNavigate("NestedRegion", new Uri("View1", UriKind.Relative));
    });
    

    UPDATE:

    One possible approach for setting the scoped RegionManager into the child ViewModel would be by using a Shared Service and get the scoped RegionManager from there.

    The Main ViewModel would store the RegionManager as follows:

    ...
    bool createRegionManagerScope = true;
    var scopedRegionManager = region.Add(view, null, createRegionManagerScope);
    var dictionary = ServiceLocator.Current.GetInstance<ScopedRegionManagersSharedDictionary>();
    dictionary[Names.ScopedRegionManagerName] = scopedRegionManager;
    this.regionManager.RequestNavigate( Names.MainRegion,
        new Uri("HelloWorldView", UriKind.Relative));
    

    And then, the child ViewModel should implement INavigationAware in order to retreive and set the scoped RegionManager on the OnNavigatedTo() method like shown below:

    void OnNavigatedTo(NavigationContext navigationContext)
    {
        var dictionary = ServiceLocator.Current.GetInstance<ScopedRegionManagersSharedDictionary>();
    
        this.regionManager = dictionary[Names.ScopedRegionManagerName];
        ...
    }
    

    I hope this helps, Regards.