Calling Navigate From The View Model

Windows Phone Mini-Tutorial

In the third part of the MVVM Light Toolkit Soup To Nuts (part 1 is here) I started with an application that had two pages, and a button on the first that was to cause a navigation to the second page.  You can download the starting source code here

In that article I explained how the VM cannot call the Navigate service, but that you could use messaging to have the View make the call.  While that is correct, there is an easier way; which is to grab the rootFrame and to call Navigate on that.

To do this, open the starting application and navigate to the GoToPage2() method that is called by the relay command.  Remove the MessageBox and instead add this line to obtain the RootFrame of the current application,

var rootFrame = (App.Current as App).RootFrame;

Once you have that in hand, you can call the navigation service directly from the View Model,

 

rootFrame.Navigate( 
  new System.Uri( "/Views/Page2.xaml", System.UriKind.Relative ));

This greatly simplifies the code and avoids the added complexity of using messaging back to the original page to perform the navigation.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Mango, Mini-Tutorial, Patterns & Skills and tagged . Bookmark the permalink.

9 Responses to Calling Navigate From The View Model

  1. KurianOfBorg says:

    Accessing a global navigator outside the view model is a violation. If the view model contains functions which require navigation (such as a PageFunction to retrieve something) then the NavigationService to be used must be passed in. Navigation to other unrelated pages should be done from just the view.

  2. This can’t be called MVVM. Why reference views in the view models? It is wrong!

    You should write a service that takes care of this that you can mock (or write a test implementation) to make sure that the VM behaves like it should. I think it is wrong to post blogs like this because everyone believes this is the correct approach…

    • CB says:

      From my understanding and use of the MVVMLight toolkit, VMs are not referencing Views at all, but merely sending messages that a View might listen for and act on.

  3. A global navigator object sounds just as bad, either way you are accessing a global.

    My view-model accepts an INavigator object as its constructor. For testing I pass in a SimpleNavigator. For the real app I use a “PhoneApplicationFrameNavigator”, which is just a simple wrapper around a PhoneApplicationFrame.

    The code is in the Granite project on Codeplex. Look for “Granite Xaml” library.

  4. Ihor Bats says:

    Yes guys, it worth but if you have application only with a few pages it’s not a problem to use this approach…

  5. Rob S. says:

    Doesn’t that kill unit-testability? I really prefer having a global navigator object that I can use to handle navigation messages.

  6. Erno says:

    I prefer to use a NavigationMap because otherwise you’d be forced to check all the Uri’s scattered though out the application when you change the folders and/or names of the views.

    • Kahuna says:

      Hi Erno,

      Would you be so kind and post an example of such a NavigationMap? I’d be interested in your way of implementation.

      Thanks a lot!

Comments are closed.