I posted similar question few months ago Working with nested views using Prism with IsNavigationTarget which can return false, I'm still not sure what is the proper way to do it.
Imagine you have a view A, in this view A you have declared a region A, then you injected a view B into this region A. Similarly, in View B you have registered region B, and then you injected a view C into this region B. As it shown on the following picture:
In the ViewModelA for ViewA, I have a method SetUpSubViews() where I call:
_regionManager.RequestNavigate("regionA", "ViewB", NavigationCallback);
ViewModelB for View B implements INavigationAware. So that in OnNavigatedTo() method I call:
_regionManager.RequestNavigate("regionB", "ViewC", NavigationCallback);
ViewModelC for View C implements INavigationAware too.
Now, I have in both ViewModelB and ViewModelC in IsNavigationTarget() method:
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return false;
}
It means I want to create new view everytime this view is navigated.
Both ViewB and ViewC implement IRegionMemberLifetime interface, where I set:
#region IRegionMemberLifetime
public bool KeepAlive => false;
#endregion
It means that I don't want to reuse view and I want it to be disposed.
And regions in the view are declared like this:
<ContentControl prism:RegionManager.RegionName="{x:Static localRegions:LocalRegions.RegionB}" />
Now, first time when I call SetUpSubViews() method on ViewModelA all is good. Second time when I call it I see the exception:
Region with the given name is already registered ...
What I need is to have a way to recreate view<->viewmodel pair from scratch everytime when I need. It seems when view is disposed, prism doesn't remove region that was declared in removed view. Question to community and prism developers, how to do it in proper way?
The current solution doesn't make happy, here is what I do: Step 1 - I set in ViewModelB and ViewModelC in INavigationAware part
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
that signals to prism to do not create new views and probably it also means that if any region is found in the view to do not register it in the region manager.
Step 2 - When i need to inject view to region, i remove manually old view and create new one. So my SetUpSubViews() method looks like this:
protected void SetUpSubViews(){
//get region by name
var region = _regionManager.Regions["regionA"];
// push to remove all views from the region
region.RemoveAll();
// navigate to view
_regionManager.RequestNavigate("regionA", "ViewB", NavigationCallback);}
Similarly I have to remove ViewC from region regionB on ViewB. (here is region.RemoveAll() is a key line.)
Step3 - I don't implement IRegionMemberLifetime interface on viewB and viewC.
It works, but it doesn't look correct.
P.S. I also tried scoped manager, but i don't know how to propagate new created scoped manager to the viewmodels, cause they are created automatically, and if i resolve it via constructor I get main global manager instead of scoped.
Thanks.