PRISM Navigation: Will Scoped Regions fire the navigation events for views in nested regions

Topics: Prism v4 - WPF 4
Jan 11, 2013 at 1:02 PM
I am using nested regions in a PRISM 4.0 WPF application and having trouble getting the Navigation events of the nested regions views to fire. We have a Region, MainContentRegion, in the Shell.xaml and I have a view, ParentView, that has nested regions with each containing a view from a different module. Each module's view model has a CompositePresentationEvent called SaveView for handling validation and providing a means for users to correct validation mistakes before navigating away from the view and saving or, by election, not saving. This event is subscribed to in the OnNavigatedTo implementation of INavigationAware. The root problem seems to be that the OnNavigatedTo, OnNavigatedFrom do not get fired in the nested views. From my research I have determined that this is related to the fact that the Parent Region has no knowledge of the child regions as all of the regions as considered to be at the same level. Will using scope for the regions cause these events to fire when the parent is navigated away from? If so then how might I set this up? If not what recommendations are there for working with nested regions in PRISM such that these events can be fired?
Developer
Jan 11, 2013 at 4:55 PM

Hi,

Based on my understanding, when implementing the INavigationAware interface, the OnNavigatedTo and OnNavigatedFrom methods of the corresponding view (or view model) will only be called when a navigation request is performed on the region containing the this view. Hence, as the inner views inside your "ParentView" are hosted in nested regions, the OnNavagitatedTo and OnNavigatedFrom methods of those views won't be called as the navigation request was called in the "MainContentRegion" and not in its inner regions. As far as I know using scoped regions won't change this behavior as the navigation request will still be called in different regions.

As a possible approach, I believe you could define your "SaveView" CompositePresentationEvent in a shared project consumed by your different modules. This way when each inner view or view model is initialized, it could subscribe to this event like you mentioned. And then when navigating the "MainContentRegion" you could publish to this event, for example in the OnNavigatedFrom method of the "ParentView" in order to notify its subscribed inner views, allowing them to react accordingly with each event handler.

I hope you find this helpful,

Agustin Adami
http://blogs.southworks.net/aadami

Jan 11, 2013 at 6:32 PM

@aadami,

For the moment, against my inner self's best judgement, we are going to pull the information together as a single view and display that within the MainContentRegion.  Based on the BRD we want to display the information that is already available in other modules but in a single view.  Using nested regions would have allowed me to prevent duplicating the code.  Unfortunately time constraints prevent me from continuing to work on this.  Fortunately we are going to be going through a refactoring effort as part of our next release and the use of nested regions is going to be a part of that effort. 

In response to your answer, and for the benefit of others, the only issue I see with your approach is in publishing the event from the parent regions OnNavigatedFrom.  Based on my understanding of INavigationAware we would not be able to stop the parent view from navigating once inside the OnNavigatedFrom method.  Given that the SaveView is being used to provide the opportunity to stop the navigation and correct any errors, or continue navigation without saving the changes, we need the SaveView to fire before reaching the OnNavigatedFrom.  Since the event would be published from the OnNavigatedFrom method of the parent view we would not be able to stop that navigation if there are errors in the nested views. 

I was trying to determine if using scoped regions would provide the "awareness" of the nested regions and cause their SaveView methods to fire before getting to the OnNavigatedFrom of the parent view.

There is possibly some form of workaround for all of this, and I could be wrong (not the first time), but as mentioned above, we have to move forward.  When we get into refactoring and work through the nested views issues, I will update the thread.

Thanks Again for taking a look at this.