whit
whit

Reputation: 127

How to RequestNavigate between views in Prism 4 with Unity IoC

I am working on a WPF pilot project using Prism and Unity and my app has 3 modules.

Module A has 2 views, Module B has 1 view, Module C has 1 view (which is essentially a main menu) and I have my shell. The shell has 3 regions, ribbonRegion, leftRegion, rightRegion.

Right now Module C's view is loaded into the shells leftRegion which has the option to run the other modules. When you select a task (this is currently the only option) Module A view1 is navigated too in the left region (replacing the main menu view) and Module B view 1 is navigated too in the rightRegion.

Module A view1 has a button to navigate too Module A view2 in the leftRegion and can go back.

This all worked great when I didn't understand LifetimeManagers, I could flip back and forth between A's view1 and view2 while always displaying B's view1, and my menu worked. However I later realized that a new instance of A's view1 and view2 were being resolved each time I Navigated to a view. This was problematic as a new ViewModel was created with each new view being resolved, but then I began to learn about LifetimeManagers so I changed from transient to controlled. But then my navigation broke.

ModuleA Definition: (same approach for B and C)

     container.RegisterType<Object, View1>(ViewNames.View1, new ContainerControlledLifetimeManager());
     container.RegisterType<Object, View2>(ViewNames.View2, new ContainerControlledLifetimeManager());

Navigation from main menu:

    regionManager.RequestNavigate(RegionNames.RightRegion, ViewNames.TifView);
    regionManager.RequestNavigate(RegionNames.LeftRegion, ViewNames.View1);

Both of these function as you would expect, the views from these 2 modules are resolved and navigated to, and View1 replaces the main menu view. The navigation breaks though when I now try to navigate to View2 from a command in View1.

    regionManager.RequestNavigate(RegionNames.LeftRegion, ViewNames.View2);

This RequestNavigate however does not work. The view is not resolved and added to the region and so the navigation does not happen. (The command does work and fires properly)

Why is View1 from module A resolved and added to the region when View2 is not? Both views are registered and navigated to in the same manner. In fact I can change the order and navigate to View2 first, and attempt to View1 second and View2 will resolve but then View1 is broken. Is there some limitation in the ContainerControlledLifetimeManager that I am unaware of?

Any help in understanding how to handle this navigation would be helpful, I'm really getting stuck on where to look for the source of this, is the problem introduced by the LifetimeManager change, or am I registering or navigating incorrectly?

Upvotes: 1

Views: 1865

Answers (2)

Sascha Minor
Sascha Minor

Reputation: 84

Had a similar issue. For me it was a exception that occured in the "OnNavigatedFrom" method of one of the viewmodels. The prism framework obviously caught the exception, but the navigation request still failed.

So the problem is not the View (Viewmodel) you are requesting to navigate to, but the view (viewmodel) you are navigating from. That's why, if you change the navigation order, the broken believed view works again.

So maybe it is a good idea to turn on first chance exceptions next time you have similar problems.

Upvotes: 0

TTat
TTat

Reputation: 1496

The View Model is the type that should have the lifetime manager, not the View.

container.RegisterType<ViewModel1>(new ContainerControlledLifetimeManager());

or if there's an interface for the VM

container.RegisterType<IViewModel1, ViewModel1>(new ContainerControlledLifetimeManager());

Another option you can do is implement INavigationAware and handle storing/restoring what you need in the containing in the OnNavigatedTo and OnNavigatedFrom methods.

Upvotes: 1

Related Questions