Navigation with MVVM

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;

        #endregion

        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
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);
                }

                return _changePageCommand;
            }
        }

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

                return _pageViewModels;
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    OnPropertyChanged("CurrentPageViewModel");
                }
            }
        }

        #endregion

        #region Methods

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

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

        #endregion
    }

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"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleMVVMExample"
        Title="Simple MVVM Example" Height="350" Width="525">

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

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

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

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)
    {
        base.OnStartup(e);

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

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

Summary

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

113 Responses to Navigation with MVVM

  1. JoachimJ says:

    I know it’s a while since you posted this, but this is still useful. Thanks for sharing!

  2. fwuellner84 says:

    Great article and very helpful in the jungle of MVVM concept interpretations for navigating between different views. I intend to use your code example as standard template for the future development of multiple-view-applications according to the MVVM pattern.

    Thanks a lot for your great work!

    Best regards

    Another Software Engineer

  3. A Grateful Programmer says:

    Um…wow…I’ve been pulling my hair out trying to figure this out. I’ve just started WPF and was struggling with how to create the Master/Detail design. Whenever I clicked a menu item, only the viewmodel’s .ToString() would show. So, it would show something like “ViewModels.ViewAViewModel” or something like that. I stumbled across some answers of yours on S.O. and followed this blog via there. It looks like a wealth of knowledge. Thank you for taking the time to do this. It really truly helps and I greatly appreciate your hard work and effort.

  4. estebanqv says:

    Hello Rachel,

    I’m in my first MVVM steps. I followed your Navigation tutorial. I have a small question:

    How can I integrate a Login Window in this navigation sample, knowing that after the user is logged the options in navigation will change?

    Thank you for your answer

  5. Dios says:

    Hello Rachel. Excellent article and blog. Two questions,

    Can the ViewModels list inside ApplicationViewModel be avoided? Because I think a huge list with concrete ViewModels will become a pain for a developer if the project become more complex.

    Also do you still implementing your projects with that way?

    • Rachel says:

      Hi Dios, sadly my current job does not have me working with WPF, so I haven’t used it much over the past few years. Yes there is ways around that, but I wanted to keep this very simple for the purpose of this blog post. If you look around on Google or Stack Overflow, I’m sure you’d find some more advanced examples 🙂

  6. Roy says:

    Thanks for this post. I could figure out the way to work with the approach shared (first one). This is helpful. Good luck with the future posts.

  7. Vijay says:

    Could you provide complete code or project for Navigation with MVVM

  8. Very nice post. I simply stumbled upon your blog and wished to say that I have really loved surfing around your weblog posts. After all I’ll be subscribing in your feed and I hope you write again soon!|

  9. ColeG says:

    Hey Rachel!

    First of all, great guide. I am trying to learn C# and MVVM at the same time and after what felt like hundreds of articles, yours was the one that finally made light bulbs go off. Thank you for that.

    I do have a question though. I want my navigation bar to have headers for groups of related pages. See the left hand side of the following UI images for reference:

    (Sorry for the size of the text on the images, hopefully you get the idea)

    I tried looking at a stackoverflow post mentioning composite collections and I tried to take that and apply it to what you had demonstrated, but I couldn’t get it to work. Here is a link the to the post for reference:
    http://stackoverflow.com/questions/5473001/itemscontrol-with-multiple-datatemplates-for-a-viewmodel

    Any ideas on how you would implement that with your MVVM format? Any direction or help will be much appreciated. Thanks again!

  10. Thank you, this was very helpful!

  11. www says:

    Thank you very much!

  12. Peter Dunn says:

    Thank you for time and clear example. I highlighted the selected button with a Style when selecting (code below), but i need help keeping the button highlighted while I work in the selected UserControl.

    Thanks for any help,
    Peter

  13. eavestn says:

    Rachel, is there anyway to use your method of updating the VM and pulling the .xaml DataTemplate configurations out into the App.xaml?

  14. Anne Jan Pool says:

    We have several applications all working according to your tutorial using the ViewModelLocator of MVVM Light and the Messenger functionality of MVVM Light. Works wonderful (thanks for the clear explanation).
    Each ViewModel is related to one View. But every time the user navigates to a page (View) a new instance of the View is created (the ViewModels are singletons, constantly listening to Messages) and the old one is not garbage collected. So memory gets fuller and fuller and the application slows down. How can I make a View be garbage collected after is has been unloaded?
    I really hope that you can help me.

    • Rachel says:

      Hi Anne,

      I’m not a big fan of the ViewModelLocator, so I’m not sure if I could help you there.

      My best guess is to double-check any event handlers to make sure nothing is holding the View in memory, or see if you can draw the View using DataTemplates rather than new instances. Its hard to tell though with my limited knowledge of ViewModelLocators and without seeing your code.

      I’d recommend posting a question on StackOverflow with some sample code to demonstrate the problem, and someone will probably be able to help you there. Feel free to post a link to the question here too, and perhaps I can take a look at it.

      Good luck!

  15. sd says:

    Thank you ms Rachel you for this simple easy to understand tutorial! I kindly ask you this:

    What would be the approach to have a “Home page” button also *inside* the products page (imagine it just below the “get product” button) which of course will navigate to the home page?

    Thank you, keep the good work! 😀

    • sd says:

      hmm just noticed the last paragraph “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”

      as i am learning MVVM i would like to avoid ready made frameworks so i can really get the knowledge of what is happening (and then later i can use frameworks). So I just would be glad if you could provide any tips on broadcasting these type of events/commands without using framework. (*gets ready for google-fu*)

      Thank you again! 😀

      • Rachel says:

        I’m sorry to say that I never bothered to make my own, so am not sure if I could help direct you in the right direction. I know there are many variations of such messaging frameworks, some Microsoft ones and some 3rd party, although the only ones I’ve used is MVVM Light’s Messenger, Prism’s EventAggregator, and CAB’s [EventSubscription] and [EventPublication] attributes.

    • Rachel says:

      In this case, I would recommend using an event broadcast system like MVVM Light’s Messenger or Prism’s EventAggregator. Alternatively, your ApplicationViewModel could set something like a ProductViewModel.HomeCommandDelegate at the time it is created

  16. RodAtHome says:

    Reblogged this on Doctor Who and commented:
    This is an excellent series of articles by Rachel on the MVVM programming pattern. Well worth reading.

  17. RodAtHome says:

    Very good article on the MVVM design pattern and navigation within a WPF app. Thank you for posting!

    I’ve got one question; where is the definition for the IPageViewModel interface?

  18. Franz says:

    Hello,

    I tried to add some Views. The buttons are shown but when I click on one of them I only get the Name of my ViewModel class? How can I connect my VIewModel with the correct View? And why is it working for 3 out of 4?

    Thank you in advance!

    • Rachel says:

      Hi Franz,

      Most likely you do not have a DataTemplate defined your your ViewModel’s object type, WPF is rendering the object using the default template which is just text containing the .ToString() of the object.

      If you add your DataTemplates it should work correctly.

      Good luck!
      Rachel

  19. Samambaia Jr. says:

    Hi, I’m a absolute begginer in MVVM and I would like to know about send data between UserControl. The both UC are on the same page. Something like List and Detail. I would like to click on a list item and show the result in the UserControl detail. How do I do? You could give me a tip or an example?

    • Rachel says:

      Hi Samambaia,

      In your example you’d ideally have a single ViewModel with both a Collection of objects, and a SelectedObject property, and each UserControl would get bound to those. If the two objects are in completely separate areas of the application and it would be difficult to have them share the same parent object model, I’d recommend looking into WPF’s event system, such as MVVM Light’s Messenger object or Microsoft Prism’s EventAggregator.

      Thanks,
      Rachel

  20. lam says:

    Hi Rachel,
    Thanks for showing this useful article which is similar to what I am trying to achieve currently: use a group of radio buttons (command binding) to switch views with MVVM. However, I failed to get it work. Is it possible for you to illustrate with your sample code to show how it can be done? Thanks.

    • Rachel says:

      Hi Iam,

      I would suggest using a ListBox that has it’s style overwritten to use RadioButtons so it keeps track of the selected item easily. Then you could bind the ItemsSource to your AvailableScreens, and bind the SelectedItem to whatever screen is currently selected.

      If you need help with such a solution, try posting a question containing the details on http://www.stackoverflow.com, and leave a link here for me and I’ll take a look (assuming someone else doesn’t help you out first!).

      Good luck with it!

  21. carpi1968 says:

    Hi Rachel,

    Wonderful post!

    Would there be a simple way to have the old view fading out and the new view fading in?

    Any suggestion woul be highly appreciated

  22. avots says:

    Hi, unfortunatelly the code can not be downloaded for some reason..
    The message I get is something like “You connected to wired.meraki.com, but you are likely not currently connected to a Cisco Meraki appliance.”

    Can you please check this?
    Thanks!

    • Rachel says:

      Hi Avots, I’m not sure why it isn’t working. I just double-checked the link and it seems OK, so perhaps it’s an issue with your internet connection? I don’t know what Meraki is, but it sounds like something specific to your network.

  23. esdee says:

    excellent mvvm series
    thanks a lot!

  24. Woj says:

    Thanks for the awesome example. How would one go about doing the view navigation using MVVM Light Messenger class??

    • Rachel says:

      Hi Woj,

      Usually I’d have my ViewModels raise an event (Messenger.Default.Send) whenever it wants to change the current screen, and my main AppViewModel would subscribe to receive these messages and change the currentContent whenever it receives one.

      • Woj says:

        So would the Send event need to be in the constructors of all my viewmodels and the register event in the constructor of the main app view model? Or would the Register event need to be in the ChangePageCommand?

      • Rachel says:

        Its been a while since I’ve used MVVM Light, however I believe it uses a singleton instance of the Messenger class, so wherever you want to change pages you’d call something like Messenger.Default.Send(…) and pass it whatever event args you want. The Register event only needs to be hooked up in whatever class is in charge of actually changing the view, such as your main app view model.

  25. danclick says:

    Hi Rachel, great articles, thanks!
    One question: I wanted to remove the “button sidebar” from the ApplicationView Windows. So, I implemented the navigation, as follows:
    -Instead having a collection of viewmodel, when application starts I set the ApplicationWiew’s Data Context to a new instance of my first view, passing to the constructor the ApplicationViewModel itself:

    CurrentPageViewModel = new HomeViewModel(this)

    so I’m injecting the ApplicationViewModel on another viewmodel.

    -To perfom navigation I created a Command that sets the CurrentPageViewModel to a new instance of another viewmodel:

    _applicationViewModel.ChangeViewModel(new AboutViewModel());

    Is this a good way to accomplish navigation in this scenario?

    Thanks!

    Daniele

    • Rachel says:

      Hi Daniele, I don’t see any problem with using that approach if that is what works with your application style.

      A few things to be careful of though is to ensure it makes sense for your ViewModels to know of each other in this way, and that’s its OK to create a new ViewModel every time that method is called.

      I’ve always been a big fan of being practical first and foremost, so if this works for you and is practical for your framework, go for it!

      Rachel

  26. Hi Rachel,

    I notice you are adding the page viewModels in your ApplicationViewModel. I can see some issues with this:

    1. The ApplicationViewModel knows about all of the concrete sub-viewModels.
    2. If the sub-ViewModels have a lot of properties or contain their own sub-viewModels then there could be a lot of viewModels open at application launch increasing the resource usage of the application.

    Take unit testing, for example. If I was testing the ApplicationViewModel, the entire object graph, including the HomeViewModel and ProductsViewModel would be in memory. In a real world application you could have 10+ pages, each of which could have their own pages (and so on). This seems a bit heavy handed where at most I should have the AppViewModel and any mocked dependencies in memory during the test of the ApplicationViewModel.

    Also, what happens if the viewModels being used as pages have their own dependencies? Who is responsible for resolving these? and if the page viewModels also have their own set of page viewModels, each with their own dependencies…

    I love the simplicity and elegance of using this approach but in my use of it I have come across the issues detailed above. I’m not currently sure of the best way of overcoming these hurdles either.

    Obviously this is an example, so I understand why the article does not address these points but I was wondering if you have come across these problems in any of the WPF applications you have written and if so what solutions you would recommend.

    • Rachel says:

      Hi Benjamin,

      A typical solution I see is the use of a NavigationService that is responsible for handling the creation and management of ViewModels and their associated Views.

      Typically it only creates a ViewModel when it’s requested for display the first time, and can handle other cases depending on your requirements, such as memory management, ViewModels that go out of scope, etc.

      In the past I will also typically use of an event system too, such as PRISMs EventAggregator or MVVM Light’s Messenger class, so the ViewModels don’t need to have a direct reference to each other.

      Hope that helps answer your questions!
      Rachel

  27. Franz says:

    Hi Rachel,

    Thank you for this beautifully written article which I am so glad I stumbled upon. I think that this is a good model for an application that I am currently converting, as a learning experience, from Delphi 7/VCL to F#/WPF/MVVM.

    Your article has helped me better understand these new technologies. I am pretty sure that I will refactor the app in its present state, with one main window view/VM and two (independent) tabs, into multiple (ultimately three) views/VM’s as per your design since that suits so much better (from both a coding and usage perspective).

    Regards,
    Franz

  28. Michael Aliotti says:

    Hi Rachel. Great blog post! I do have some questions, though:

    1) How would you handle passing parameters from one ViewModel to the next? In other words, a command is triggered on ViewModel1 and the application switches to ViewModel2, but ViewModel2 needs a parameter from ViewModel1.

    2) When instantiating the list of ViewModels, what would be the best approach for ViewModels that rely on parameters from other ViewModels? Should they be added to the list with default parameters? Could the default parameters be changed when the ViewModel they depend on passes the parameters to them?

    Any help is much appreciated!

    • Rachel says:

      Hi Michael,

      Typically we would use some form of messaging system to communicate between ViewModels. I’d recommend Microsoft PRISM’s EventAggregator or MVVM Light’s Messenger, or if you really wanted to you could also build your own instead.

      I have a brief overview of them here if you’re interested : Communication Between ViewModels with MVVM

      Good luck with your project!

      Rachel

  29. peter says:

    I noticed that in your ApplicationViewModel you have a list of ViewModels, which is composed by a new instance of each ViewModel. Can this method lead to performance issues or is this the standard way?

    Thank You

    • Rachel says:

      I’m sure it could, and you could lazy-load the ViewModels as needed instead of creating them all initially. It depends on how big your ViewModels are 🙂

  30. Syn says:

    This is an excellent article, thank you.

  31. Deno says:

    How does this app gets the correct View by the ViewModel? Where is it stated that the HomeViewModel is connected with HomeView?

    I added for example an another ViewModel to the PageViewModels list, and it automatically adds the button with the correct newly created custom View… I just don’t get it, how is that possible? I’ve never stated that this new ViewModel is connected with the new View.

    Command=”{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}”
    CommandParameter=”{Binding }”

    Is it because of this? What’s Relative AncestorType={x:Type Windows} doing? And why is CommandParameter binding to nothing?

    C# and MVVM looks really fun way of programming, but it’s pretty abstract technique for me…

    • Rachel says:

      Hi Deno,

      The ContentControl has it’s Content property bound to the CurrentPageViewModel. By default, WPF doesn’t know how to draw a ViewModel, however I have defined a DataTemplate in the .Resources of the application to tell WPF that it should draw anything of type HomeViewModel with HomeView, and ProductsViewModel with ProductsView.

      The Command binding only ties the button click event with the ChangePageCommand in the ViewModel. Because of the way the DataContext behind the UI controls gets inherited, we need to use a RelativeSource binding to tell it to look in Window.DataContext for the ChangePageCommand. The empty binding is simply a shortcut way to refer to the current DataContext, so it is passing in the selected IPageViewModel to that command.

      If you’re new to WPF, I’d suggest reading my articles Understanding the change in mindset when moving from Winforms to WPF and What is this “DataContext” you speak of?. I think they may help answer some of your questions related to bindings, the DataContext, and MVVM.

      • Deno says:

        Wow thanks for you quick reply.. and this blogs contains very useful information, I didn’t knew about that huge basic WPF article. I’ve improved a lot since I asked that question but I’m still a beginner, so I’m still going to look into it… thank you!

      • rajesh says:

        Hi Rachel,

        You have mentioned in the article that “Button’s DataContext is the PageViewModel, so you used a RelativeSource binding to find the ChangePageCommand”.
        I am struggling to understand how it is that Button’s DataContext is PageViewModel? Can you please shed some light on it.
        I have read your article explaining DataContext, from which I can infer that if a DataContext is not set for an element, it inherits it from it’s Parent element. Here I see that DataContext is not specified for any of the element except for Window element(specified in App.xaml.cs) whose DataContext is ApplicationViewModel. So, for me Button’s Datacontext should be ApplicationViewModel.
        What am I thinking wrong here?

      • Rachel says:

        Hi Rajesh, to understand the DataContext inheritance here you need to understand how an ItemsControl works.

        An ItemsControl will take each item in the ItemsSource, create a copy of the UI objects in the ItemsPanelTemplate, and assign the DataContext of those UI objects equal to the item in the ItemsSource. You can read more about the ItemsControl here if you’re interested.

        So in this case, the ItemsControl is bound to a collection of PageViewModels, so it will create an instance of the ItemsPanelTemplate for each PageViewModel and assign the DataContext equal to PageViewModels[n] on each one.

        Hope that helps,
        Rachel

  32. Walter says:

    Thanks for this example,

    I never used my vm for navigation before, and have a question about the ApplicationView.

    I like to use (restyle) radiobuttons for switching views. This way the user can see which view is selected. How about setting the right radiobutton to IsChecked when changing the view in the viewmodel.

    Walter

    • Rachel says:

      Hi Walter,

      Typically for something like that where I want to track the SelectedItem, I would use a ListBox that is styled to use RadioButtons. You can find an example here.

      Good luck with it,
      Rachel

  33. Farid says:

    Hi Rachel,

    Thanks a lot. It’s exactely what i’ve been searching during this week!
    Now I would like to use builtin Ribbon control to load my viewmodels.
    I’ve tried to modify your source to do that but my Ribbon button is always disabled???

    • Rachel says:

      Hi Farid, you might want to post a question on StackOverflow about it, along with a small sample of your source code.

      I haven’t worked with the Ribbon control before, and wouldn’t be of much help without seeing your code.

      Thanks,
      Rachel

  34. Naveed Quadri says:

    Hi Rachel,
    I am (WPF Newbie) working on a navigation based application, where i have abt 10 views. I am trying to understand why are we not using the NavigationService built in WPF.
    I would really appreciate it if you could tell me or point to a resource on this topic.
    Thanks
    Naveed

    • Rachel says:

      Hi Naveed,

      Honestly, I have not used the NavigationService before. I can’t remember my exact reasons for it, but I believe it was because I thought it mixed the data and UI layers too much.

      I always found it easier to let my application (ViewModels) control the application flow, and leave the UI side of things out of the application layers entirely.

      For me, my UI layer is simply a visual representation of my application layer, and I didn’t like having my application layer worry about how to draw each page.

  35. Mitesh says:

    Hi!

    My question is related to following article where you posted your answer.

    Ref: http://stackoverflow.com/questions/7446825/open-child-window-inside-a-parent-window-in-wpf-using-mvvm

    I am using MVVM framework and the technique you have mentioned in your following post

    Navigation with MVVM

    This is the same technique I am using to implement my WPF application. I am building new WPF application and want to use pure MVVM i.e. no code behind.
    Now I want to open dialog window or Child Window on top of application window using a button click on current application window. In that window I want to show some data in data grid and want to give facility to filer those data in grid to search specific data in grid and then want to give user a functionality where user can select specific row from grid and hit “OK” or “Cancel”.
    Now my problem is How can I open this window on top of application window? How can I know that which record user have selected? and once user click “OK” or “Cancel” I want that window to go away and do some operation based on selection.

    Do you have any sample for this scenario? Or could you give any sample for this scenario?
    I can share my solution with you if you want.

    Thanks in Advance.

    Mitesh.

    • Rachel says:

      Hi Mitesh,

      For me it typically depends on what kind of dialog it is.

      If it is something like a File/Folder dialog, I usually refer to that from the ViewModel layer.

      If it is something like a popup window that contains child content, I usually use a custom Popup Control in my UI layer, and manage properties like IsPopupVisible and PopupContent from the ViewModel layer.

      And a 3rd solution is to have a class that is solely responsible for managing dialogs, and use a messaging system to trigger when dialogs appear and what content they should contain.

      In your example, I would probably go with the 2nd option of having the ViewModel contain the dialog content (including the SaveCommand and CancelCommand), and have the XAML be written in such a while that it provides a visual representation of your Dialog data when needed.

  36. AdamAdam says:

    Thank-you for this article, it really helped me! 🙂

    • Adam says:

      I’m trying to work out why when I switch pages it keeps the previous page running because when I added a MessageBox to the Background worker in my Overview page it kept calling even on other pages and when I clicked Overview again it just added another Overview because I was now getting 2 notices incrementing on clicking Overview button every loop, and so on.

      Has anybody experienced this issue?

      • Rachel says:

        Hi Adam,

        Make sure you’re changing to the existing ViewModel, and not creating a new one each time to switch to the page. And don’t forget that changing pages doesn’t remove or dispose of the old page at all – it just changes the active page.

        If you’re having problems with your code, I’d encourage you to post a question on stackoverflow.com and include the relevant parts of your code. You should get an answer fairly quickly, or you can email me the link to your question if you want.

        Good luck with it =)

  37. Alex F says:

    Hello,
    I’m using your example and wanted to know how I can pass parameter to my user control? My application will have a menu on the left (TreeView most likely) and when user clicks an item in context menu of the tree, I load a User Control on the right side. The user control will need and ID or more parameters to be passed to it so it can populate it’s View.
    I would appreciate it if you could let me know how to implement this.

    Thanks.
    Alex

    • Rachel says:

      I would have the Model object containing the data for your UserControl in your ViewModel, and simply set the DataContext to be the object in your ViewModel.

      Its hard to post a lot of code in these comments, but ideally I’d have my ViewModel contain an ObservableCollection of MyObject classes for the TreeView.ItemsSource to bind to, and a SelectedObject property of type MyObject. Then I would have the UserControl simply bind it’s DataContext to SelectedObject.

      • Alex F says:

        Thanks for your reply. I’m still not clear how to do this. Is it possible to point me to an example where TreeView item event will switch between User Controls and able to pass parameter to user control so it can get populated?

        Thanks,
        Alex

      • Rachel says:

        The best example I can find is this answer of mine on StackOverflow. It uses Page objects, however you could do something similar with your objects.

        If you have further questions, I’d recommend posting them on that site along with a short code sample demonstrating your problem. They’re pretty good at helping you figure out your problem quickly.

  38. Arishtat says:

    Hmm, if you add a menu and bind the command to a MenuItem in a similar fashion, the MenuItem is disabled even though the CanExecute method always returns true. Can’t quite figure out why.

    • Rachel says:

      Hi Arishtat,

      Perhaps you could post a question on StackOverflow with a code sample outlining the problem, and send me a link. Its hard to tell what the problem would be without seeing the code, however a common problem I see with Menus is they’re sometimes not part of the same Visual Tree, so the DataContext isn’t what you’d expect it to be.

  39. Amit Sharma says:

    Nice post Rachel. While using this, I’m facing a problem (or may be it is by design) – each time I switch back to a different viewmodel, a new VIEW instance is created.

    Binding on mainview xaml –

    When I switch back and forth to let’s ActiveViewModel – X, the view associated with X is re-instantiated (I can verify it by seeing view constructor getting hit in debugger).

    It leads to subtle bugs as my view has a DataGrid and if user changed some filter, groups – on re-instantiating the view, all these changes are gone.

    Note – my viewmodel data is retained each time so I don’t have same issue as other folks above.

    • Rachel says:

      Hi Amit,

      By default, WPF unloads objects that are not visible, so it sounds like your UserControl is getting unloaded when its hidden, then a new copy of it is loaded when you switch back, which causes all changes made to properties that are not bound to something in the DataContext to be reset.

      What I usually end up doing to avoid this behavior is reusing a custom TabControl control which stores the ContentPresenter of each TabItem when you switch tabs, and reloads the same ContentPresenter when you switch back. This preserves the control’s state when it’s not visible, and reloads it just as it was when you navigated away from it.

      An example of the code and how it works can be found in this StackOverflow answer of mine. Perhaps I’ll write this solution up as my next blog post, as I think the original site I got the idea and most of the code from no longer exists 🙂

      Good luck with your project,
      Rachel

  40. Kissack says:

    Hello Rachel,
    I’m a total beginner with WPF and MVVC. Followed your example but having a little problem. Once I leave one view and return to it again the ViewModel’s constructors for that view is called and looses its state. Why is that and how can I avoid it ?

    • Rachel says:

      Hi Kissack,

      WPF unloads resources which are not in use, which includes non-visible UI objects, so it sounds like your View is initializing a new ViewModel as its DataContext when the View loads, which is usually not something I recommend.

      Check your View’s constructor, Loaded event, or XAML and see if the DataContext is being set anywhere to a new instance of your ViewModel.

      • Kissack says:

        Hi Rachel, the view was one older experimental, where a data context was being set in XAML, so the ViewModel was recreated. When I removed it, the state is maintaned. Thank you for your time…

      • Lora says:

        Hi, I have the same problem, would you mind to explain it? I dont know how to set the DataContext to not lose the state. Thanks.

      • Rachel says:

        Hi Lora,

        If your current bound controls appear to be losing their state, then you’re probably resetting the DataContext they are bound to somewhere, such as setting the DataContext manually in the code-behind your controls.

        Usually you do not want to ever set the DataContext from the code behind your UserControls, as you are supposed to pass the DataContext to your UserControl at the time it gets used, and setting it explicitly in the code-behind will prevent that from happening.

        If you’re struggling to understand the DataContext, I’d recommend reading a recent blog post I wrote: What is this “DataContext” you speak of?

        Goodluck with it,
        Rachel

  41. Jeff says:

    Thanks Rachel!

  42. Jeff says:

    Nice example. Working on a POS design where the initial screen is a keypad login. So, in this example, i’m stuggling with how you would start out with a login view. Once the user logs in then navigate to the home page???

    • Rachel says:

      In the past when I’ve done a login screen, I show and validate the login before the main application even launches in the OnStartup method of app.xaml.cs

      protected override void OnStartup(StartupEventArgs e)
      {
          base.OnStartup(e);
      
          var login = new LoginDialog();
          var loginVm = new LoginViewModel();
      
          login.DataContext = loginVm;
          login.ShowDialog();
      
          if (!login.DialogResult.GetValueOrDefault())
          {
              Environment.Exit(0);
          }
      
          // Providing we have a successful login, startup application
          var app = new ShellView();
          var context = new ShellViewModel(loginVm.CurrentUser);
          app.DataContext = context;
          app.Show();
      }

      Hope this helps =)

      • Jeff says:

        Ok, makes sense. Question, per your suggesstion I added a logindialog window and that appears on startup. However, after logging in ok, the app just closes (ShellView never appears). Anything come to mind?

      • Rachel says:

        Set the Application.ShutdownMode to something other than the default value of OnLastWindowClose. I usually use OnExplicitShutdown

      • Hal says:

        Hey Rachel

        What should I pass in my login fuction (logindialog window) to close it and then open ShellView, was trying different solutions and nothing happened to open ShellView…

        I even added “Application.ShutdownMode: like you wrote before.

        Thanks in advance.

      • Rachel says:

        Hi Hal, if you’re using ShowDialog to show the login window, then the code in your OnStartup should resume once your login dialog returns a DialogResult

  43. Nilow says:

    Nice example,

    Tried it in my application, because I didn’t want to use Prism for this small app.

    The only thing I want to change, is instead of putting all the buttons on the shellview / applicationview, I just want to register the views in the shellview. Then adding buttons on different views, which set the IPageViewModel CurrentPageViewModel on the shellview to the appropirate view.

    But my problem is that I cannot reach the List PageViewModels from my viewmodels, and set the CurrentPageViewModel from there.

    How can I solve this?

    • Rachel says:

      Hi Nilow,

      Usually I use some kind of Event System for communication between ViewModels. Typically I’ll have my ShellViewModel listen for something like ChangePageEvents, and any button which should change the page simply broadcasts a ChangePageEvent message, which will get picked up and executed by the ShellViewModel.

      I wrote a brief overview of what event systems are and how they work at the link above, although someday I hope to write a more comprehensive guide to how to use one.

  44. Vidar Lund says:

    Rachel,
    Thanks for your excellent examples. You explain things without assuming that the audience knows a lot. I especially liked your comment that the ViewModels are the application, forget about the Views, they are just a distraction.
    Wish that you did this example using MVVM Light but I’ll sort it out. Believe that the main difference is that the logic you have put in ApplicationViewModel needs to be in the ViewModelLocator which is loaded upon starting the application in MVVM Light.

    • Vidar Lund says:

      I sorted it out. The solution was to make a top level ShellVM that handles the navigation just like your ApplicationVM. Trying to put the navigation logic in the VMLocator was a mistake.

      • Rachel says:

        Glad you got it sorted out. I don’t actually use a ViewModelLocator if I can help it, because I feel like it’s a bit limiting and I’ve had some issues with it in the past.

  45. Benjamin Gale says:

    Thanks for the excellent article.

    I thought the use of a DataTemplate to discover which view to use for each viewmodel was really clever!
    This really helps to keep the View separated from the ViewModel and means that a different Window could use a different View for the same ViewModel without any changes to the ViewModel.

    Do you have any ideas about how the lifetime of the each view is managed by WPF? If i had a large number of views to switch between, for example, how could I dispose of the views no longer in use?

    • Rachel says:

      Hi Benjamin,

      WPF will automatically unload the View once it’s no longer visible. For example, if you have a TabControl with ViewA in one tab, and ViewB in another tab, then switching from the ViewA tab to the ViewB tab will automatically unload ViewA and load ViewB.

      • Benjamin Gale says:

        Hi Rachel, thank you for replying.

        Does your comment above apply to all WPF views or is it specific to the TabControl?

        E.G. in your code example, does clicking the “Home” button completely dispose of the products user control?

        Are you aware of any situations where this automatic behavior could cause unexpected memory leaks?

      • Rachel says:

        It should apply to all controls, not just the TabControl. WPF will only load controls that are currently visible on the screen.

      • Benjamin Gale says:

        I used WPF Inspector to check this out earlier and it appears the visual tree does change when I switch between the home and the products pages.

        Thank you again for your reply it was much appreciated. I look forward to your next blog post.

  46. Ricardo Duran says:

    Hello Rachel,

    Thanks for your example of navigation.

    I am new in WPF and MVVM, I am learning.

    I followed your example and every thing work fine.
    In my mainwindow, I have four buttons to call differents user control, like Home page, products, devices and device list.

    I the “Device List” I have a button. When I click the button, a listbox needs to be filled with data.

    My problem is: When I click the button, nothing happend, but if I click a button to call for example the Home Page and then click the button to call “Device List” again, I can see now the listbox with all information that I read from tyhe database.

    Do you have any idea of this problem?

    Thanks in advanced for your help

    Ricardo

    • Rachel says:

      Hi Ricardo,

      It’s hard to tell what the issue is without seeing some code, however I am assuming the Button is on the DeviceView, so the click event should be handled in the DeviceViewModel via a RelayCommand.

      Perhaps you can post a question on http://www.stackoverflow.com outlining your problem, along with some sample code, and someone can help you out.

      Goodluck with it,

      Rachel

  47. Mark Wiskochil says:

    Thanks for an easy to understand but very powerful and useful article. I am using this method on my current project. It works very well. The only change I made was to check if the view model you want to change to is the one you are currently on, I don’t change the view model.

    • Rachel says:

      Hi Mark, glad you like the article!

      Definitely alter the shell class to suit your needs, and don’t stick with what I have here! Its not really meant to be a concrete class anyways – instead its more of an abstract idea which you can alter to fit the navigation style of whatever project you’re working on. It’s usually different for every project I work on, however all of them navigate with some kind of Application or Shell ViewModel that has a similar concept to this.

  48. Radu says:

    Rachel,

    I really like a lot your approach, it is definitely a way out to solve the navigation issue I currently have. In one of your posts on stackoverflow related to navigation, you recommended to get rid of defining DataContext in the UserControl:

    http://stackoverflow.com/questions/8677500/wpf-mvvm-load-an-usercontrol-at-runtime

    How can I solve the “Blendability” (sample data visible in Expression Blend) of the user controls in this way? Currently I followed the method described in MVVM Light toolkit. Having a Locator class, by using the Unity IoC it separates design time data from the runtime data so Expression displays sample data in my user controls.
    Once I switch to the ContentControl and DataTemplate way, I cannot have design data anymore, as the DataContext which I currently use would break the approach you suggest. Can you please help me with an idea related to this matter? I still want to have my user controls blendable.

    Many thanks,
    Radu

    • Rachel says:

      Hi Radu,

      I don’t use Expression Blend a lot, but I believe you can use the d: prefix to specify a design-time DataContext. This will allow your UserControls to have a DataContext when in the Designer, but not hard-code the DataContext into your UserControl

      <UserControl 
          mc:Ignorable="d" 
          d:DataContext="{Binding DesignTimeDataContext}" 
          ... >
      

      I’m not positive, but I believe the design-time markup extensions were added in VS2010, so I think ViewModelLocators were frequently used prior to that to solve the Blendability problem you’re describing. Personally I don’t like using ViewModelLocators at all (Some of the reasons can be found here)

      Good luck with your project,
      Rachel

  49. Bob says:

    Very nicely written article Rachel, this helped me out no end with navigation in MVVM.

    The code displayed above for the ApplicationViewModel has a list to hold the view models, I could be wrong but neither of the declarations have the generic type stated, should it not be something like:

    private List _pageViewModels;

    If so I think the property needs to be changed to follow suit.

    Thanks :)!

  50. Prasanth Guruprasad says:

    Goodness, you are still using Windows XP? When are you planning to move to Win 7 (and Win 8)?

    • Rachel says:

      lol I have Windows 7 at work, but both my home computers are XP. They’re built for gaming so slightly more expensive and I haven’t really had a need to replace them yet.

Leave a reply to Rachel Cancel reply