Navigation with MVVM

December 18, 2011

When I first started out with MVVM, I was lost about how you should navigate between pages. I’m a firm believer in using ViewModels to do everything (unless it’s View-specific code), and that the UI is simply a user-friendly interface for your ViewModels. I did not want to create a button on a page that has any kind of code-behind to switch pages, and I didn’t like the idea of my navigation being spread out throughout all the ViewModels.

I finally came to realize the solution was simple: I needed a ViewModel for the Application itself, which contained the application state, such as the CurrentPage.

Here is an example that builds on the Simple MVVM Example.

The ViewModel

Usually I name the ViewModel ApplicationViewModel or ShellViewModel, but you can call it whatever you want. It is the startup page of the application, and it is usually the only page or window object in my project.

It usually contains

    List<ViewModelBase> PageViewModels
    ViewModelBase CurrentPage
    ICommand ChangePageCommand

Here is an example ApplicationViewModel that I would use to go with the Simple MVVM Example.

    public class ApplicationViewModel : ObservableObject
        #region Fields

        private ICommand _changePageCommand;

        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;


        public ApplicationViewModel()
            // Add available pages
            PageViewModels.Add(new HomeViewModel());
            PageViewModels.Add(new ProductsViewModel());

            // Set starting page
            CurrentPageViewModel = PageViewModels[0];

        #region Properties / Commands

        public ICommand ChangePageCommand
                if (_changePageCommand == null)
                    _changePageCommand = new RelayCommand(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);

                return _changePageCommand;

        public List<IPageViewModel> PageViewModels
                if (_pageViewModels == null)
                    _pageViewModels = new List<IPageViewModel>();

                return _pageViewModels;

        public IPageViewModel CurrentPageViewModel
                return _currentPageViewModel;
                if (_currentPageViewModel != value)
                    _currentPageViewModel = value;


        #region Methods

        private void ChangeViewModel(IPageViewModel viewModel)
            if (!PageViewModels.Contains(viewModel))

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);


This won’t compile right away because I’ve made some changes to it. For one, all my PageViewModels now inherit from an IPageViewModel interface so they can have some common properties, such as a Name.

I also created a new HomeViewModel and HomeView since its hard to demonstrate navigation unless you have at least 2 pages. The HomeViewModel is a blank class that inherits from IPageViewModel, and the HomeView is just a blank UserControl.

In addition, I added an s to ProductsViewModel since it really deals with multiple products, not a single one.

An added advantage to having a ViewModel to control the application state is that it can also be used to handle other application-wide objects, such as Current User, or Error Messages.

The View

I also need an ApplicationView for my ApplicationViewModel. It needs to contain some kind of Navigation that shows the list of PageViewModels, and clicking on a PageViewModel should execute the ChangePage command.

It also needs to contain a control to display the CurrentPage property, and I usually use a ContentControl for that. This allows me to use DataTemplates to tell WPF how to draw each IPageViewModel.

<Window x:Class="SimpleMVVMExample.ApplicationView"
        Title="Simple MVVM Example" Height="350" Width="525">

        <DataTemplate DataType="{x:Type local:HomeViewModel}">
            <local:HomeView />
        <DataTemplate DataType="{x:Type local:ProductsViewModel}">
            <local:ProductsView />

        <Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
            <ItemsControl ItemsSource="{Binding PageViewModels}">
                        <Button Content="{Binding Name}"
                                Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                CommandParameter="{Binding }"

        <ContentControl Content="{Binding CurrentPageViewModel}" />

In this example, I’m using an ItemsControl to display my PageViewModels. Each item is drawn using a Button, and the Button’s Command property is bound to the ChangePageCommand.

Since the Button’s DataContext is the PageViewModel, I used a RelativeSource binding to find the ChangePageCommand. I know that my Window is the ApplicationView, and it’s DataContext is the ApplicationViewModel, so this binding looks up the VisualTree for the Window tag, and gets bound to Window.DataContext.ChangePageCommand.

Also note that I am putting DataTemplates in Window.Resources to tell WPF how to draw each IPageViewModel. By default, if WPF encounters an object in it’s visual tree that it doesn’t know how to handle, it will draw it using a TextBlock containing the .ToString() method of the object. By defining a DataTemplate, I am telling WPF to use a specific template instead of defaulting to a TextBlock.

If you are continuing from the Simple MVVM Example, I moved the ProductView out of a ResourceDictionary and into a UserControl to make this simpler.

Starting the Example

The last thing to do is change App.xaml to make ApplicationView and ApplicationViewModel our startup, instead of ProductView/ProductViewModel.

public partial class App : Application
    protected override void OnStartup(StartupEventArgs e)

        ApplicationView app = new ApplicationView();
        ApplicationViewModel context = new ApplicationViewModel();
        app.DataContext = context;

Run the project and you should see something that looks like the images below, which quickly switches the CurrentPage when clicking on the Navigation buttons.

Screenshot of HomeHome

Screenshot of ProductsProducts


And there you have it. A simple navigation example with MVVM.

You can download the source code for this sample from here.

Once you get more comfortable with WPF, I would recommend looking into using a Messaging System, such as MVVM Light’s Messenger, or Microsoft Prism’s EventAggregator to broadcast ChangePage commands from any ViewModel so you wouldn’t need to find the ApplicationViewModel to execute the ChangePageCommand, however that’s for another day.

<< Back – A Simple MVVM Example
>> Next – Communication between ViewModels