Home > C#, MVVM, Windows Phone, WinRT > NavigationService in MVVM Light V5

NavigationService in MVVM Light V5

10/10/2014

Two days ago, at Xamarin Evolve conference in Atlanta, has been announced the availability of MVVM Light V5. This release contains interesting updates for Xamarin, as we can read in the official blog post.

Another important news is the inclusion of the INavigationService and IDialogService interfaces with corresponding implementations on supported platforms. They are objects that very often are created in each project, so now we can use the existing classes instead of creating new ones.

Let’s see how to use the INavigationService interface in our Universal Windows apps. First of all, we need to add a reference to MVVM Light V5 using NuGet:

Adding MVVM Light V5 to the project

Adding MVVM Light V5 to the project

Creating the NavigationService is straightforward. In the ViewModelLocator class we write something like this:

public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    var navigationService = this.CreateNavigationService();
    SimpleIoc.Default.Register<INavigationService>(() => navigationService);

    SimpleIoc.Default.Register<IDialogService, DialogService>();

    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register<DetailsViewModel>();
}

private INavigationService CreateNavigationService()
{
    var navigationService = new NavigationService();
    navigationService.Configure("Details", typeof(DetailsPage));
    // navigationService.Configure("key1", typeof(OtherPage1));
    // navigationService.Configure("key2", typeof(OtherPage2));

    return navigationService;
}

In the CreateNavigationService method (lines 14-22), we create a new instance of the NavigationService class (that is contained in the new GalaSoft.MvvmLight.Views namespace). We need to call its Configure method to associate each page type with a key. For example, at line 17 we associate the Details key with the DetailsPage page. Then, in the class constructor, we register the INavigationService interface specifying the concrete object that must be returned when it is requested (line 6).

Now, we can define the MainViewModel as follows:

public class MainViewModel : ViewModelBase
{
    private INavigationService navigationService;

    public RelayCommand DetailsCommand { get; set; }

    public MainViewModel(INavigationService navigationService)
    {
        this.navigationService = navigationService;

        DetailsCommand = new RelayCommand(() =>
        {
            navigationService.NavigateTo("Details", "My data");
        });
    }
}

When the DetailsCommand command is executed, at line 13, we invoke the NavigateTo method on the INavigationService reference, specifying the key that corresponds to the page to navigate to (DetailsPage, in this example). We’re using simple strings to control the navigation, so ViewModels don’t need to know the Views that will be actually opened (and thus without breaking the MVVM pattern).

We’re calling an overload of the NavigateTo method that accepts an object parameter that will be passed to the OnNavigatedTo method of the requested page (in the Parameter property of NavigationEventArgs):

public sealed partial class DetailsPage : Page
{
    // ...

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        var parameter = e.Parameter as string;  // "My data"
        base.OnNavigatedTo(e);
    }
}

Of course, as we’re following the MVVM pattern, we don’t want to use code-behind. So, the preferred approach to get navigation parameters is the one presented in the article Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT to automatically pass this parameter to the ViewModel.

Lastly, the INavigationService interface exposes also the GoBack method, that allows to return to the previous page in the navigation stack.

Categories: C#, MVVM, Windows Phone, WinRT
  1. pp
    15/10/2014 at 08:21

    To implement custom NavigationService you used NavigationService from System.Windows.Navigation? Could you share your implementation of INavigationService?

    • 15/10/2014 at 08:28

      No, I don’t use System.Windows.Navigation. As I said in the article, I use INavigationService and NavigationService that are included in MVVM Light V5 (no explicit implementation is needed).

  2. 18/10/2014 at 17:10

    I think we can use a component to register the page we navigate to and avoid to use code-behind to get the data, I think on it and tell you later…

  3. 19/10/2014 at 17:16

    no I think using a dictionary of pages to manage navigation and messenger and loaded event in details page to get the data

  4. 20/10/2014 at 09:31

    I wrote a little article with my own implementation http://codepassion.azurewebsites.net/my-navigationservice-for-universal-apps/ read it and tell me…

  5. Radek
    18/11/2014 at 22:10

    I’ve installed MVVM Light 5.0.2 and have tried to implement NavigationService:
    navigationService.Configure(“Details”, typeof(DetailsPage));

    but the Configure method can only take (string key, Uri targetUri), so I’m a little bit confused with your code. Can you explain how you can use “typeof(DetailsPage)”?

  6. Radek
    18/11/2014 at 22:35

    OK – I’ve just noticed that you used Windows App in your sample and I was using Windows Phone 8.

  7. 28/11/2014 at 18:41

    Hello,
    thanks for this article – it helped a lot. But I have one question related to universal apps.

    If my XAML pages aren’t shared (seperate MainPage in Windows and Windows Phone), how can the NavigationService be implemented, if it is in the Shared Project?

    Hope you understand my issue.
    When not, I try to visualize it:

    myapp.Windows
    – MainPage.xaml
    – AnotherPage.xaml
    myapp.WindowsPhone
    – MainPage.xaml
    – AnotherPage.xaml
    myapp.Shared
    ViewModel
    – ViewModelLocator.cs

    Cheers, Julian

    • 28/11/2014 at 18:48

      If Windows and Windows Phone use pages with the same type and name, you can configure the NavigationService in the ViewModelLocator, as described in the article, because page types are actually the same, so they can be safely used in the shared project. Otherwise, you need to use conditional compilation to configure the service for each Platform.

      • 28/11/2014 at 18:52

        Thanks for the fast reply🙂

  8. Piotr
    19/12/2014 at 00:50

    Hi,
    You said, that not use System.Windows.Navigation and didn’t create custom, but in MVVM Light V5 exist only INavigationService. Today, I download new version. Do you know where is the problem ?

  9. Piotr
    19/12/2014 at 20:33

    WPF

    • 21/12/2014 at 01:24

      MVVM Light doesn’t provide an implementation of INavigationService for WPF because this platform doesn’t have a standard navigation system.

  1. 10/10/2014 at 21:50
  2. 13/10/2014 at 13:34
  3. 14/10/2014 at 18:13
  4. 20/10/2014 at 09:30
Comments are closed.
%d bloggers like this: