In what order does Prism navigation instantiate/navigate nested regions/views/VMs?

Topics: Prism v4 - WPF 4
May 12, 2014 at 11:40 AM
I've got a view/view-model (let's call it the "parent") that retrieves data in its OnNavigatedTo method. This view contains several regions of its own - these regions' views are always the same, so they are registered during application startup using the "regionManager.RegisterViewWithRegion(...)" syntax.

After retrieving the data and performing some calculations on it, the parent VM publishes an event aggregator message to say that the data is ready. The "child" VMs subscribe to this event from within their constructors, and it's in these event handlers where I extract the data that gets bound to their views.

For the last 12 months this approach has been working fine, but the application has recently been dealing with some larger data sets and I'm starting to find that (intermittently) the parent VM's OnNavigatedTo completes before the child views/VMs have been instantiated, resulting in "empty" child views (because the parent publishes the EA message before the child VMs constructors have been called, so there are no subscribers).

I had assumed Prism would do stuff like this sequentially, i.e. when navigating to the parent view/VM it would call its OnNavigatedTo before starting navigation of the child regions? Or is some of this happening on b/g threads, meaning there is no guarantee to the order in which Prism navigation does stuff?

If this is the case, what are my options? Could I simply get rid of the "RegisterViewWithRegion" startup code, and instead populate the child regions from within the parent VMs OnNavigatedTo, using "regionManager.RequestNavigate(...)"?
May 12, 2014 at 7:32 PM

First, I would like to say that based on my understanding Navigation is performed on each Region independently. Therefore, it would not be a concrete sequential execution between Navigation on different Regions.

Then, I believe the approach you suggest would work correctly, but it does not seem to be pretty elegant.
However, another approach you could perform would be similar to the following thread's solution:

Basically, Registration and initializing of Views/ViewModels should be implemented on Modules Initialization process. Then, in order to be sure that every View would be already instantiated, you could raise a InitializationComplete Event at the end of Bootstrapper's run() method, which would be the trigger for parents ViewModels to Publish() the EventAggregator Message for their child Views. You may find detailed information in the above linked discussion thread.

I hope this helped,

Gabriel Ostrowsky.
May 13, 2014 at 8:24 AM
My application doesn't use modules or MEF, so I don't think the proposed solution is relevant. Mine is a self-contained application with all views/VMs "living" in the main WPF project. I do still have an application "bootstrapper" where I register everything with the IoC container (including the views/VMs), and in its InitializeShell() method is where I use regionManager.RegisterViewWithRegion() to register the "child" views with the corresponding regions in the "parent" view.

All of the views in question are singletons, so I guess another option could be to force them to instantiate in (say) InitializeShell(), ensuring that they've subscribed to the event in their constructors? Still not particularly elegant though.

Thanks again
May 13, 2014 at 5:29 PM
Hi andyste,

Regarding your elegant concern, you could create a Registration class which would perform the process of Regions and Views Registration as it would occur on an IModule implemtened class. This way, you would only call this class from the BootStrapper to properly handle registration instead of having Regions Registering methods directly on InitializeShell().

However, an elegant design solution with Bootstrapper would correlate the use of at least one Module in order to separate the core Project with the concrete implementation and logic of Views and ViewModels. You may see some examples of One-Module and Bootstrapper solution on the Commanding and UI Composition QuickStarts.

Find more information about Modular Applications in the following MSDN Prism Guide chapter:

I hope this helped you,

Gabriel Ostrowsky