WinRT: MVVM Navigation and a MVVM Example App
Until we get the great frameworks like Caliburn.Micro up-to-date with WinRT, one possible solution for doing navigation when using MVVM pattern is to wrap the Frame-object. Here’s a simple implementation (which could be further enhanced by extracting an interface from it):
public class NavigationService
{
readonly Frame frame;
public NavigationService(Frame frame)
{
this.frame = frame;
}
public void GoBack()
{
frame.GoBack();
}
public void GoForward()
{
frame.GoForward();
}
public bool Navigate<T>(object parameter = null)
{
var type = typeof(T);
return Navigate(type, parameter);
}
public bool Navigate(Type source, object parameter = null)
{
return frame.Navigate(source, parameter);
}
}The NavigationService can be initialized by passing in the root frame, for example in the App.xaml.cs where the root frame is created:
// Create a Frame to act navigation context and navigate to the first page
var rootFrame = new Frame();
App.NavigationService = new NavigationService(rootFrame);
rootFrame.Navigate(typeof(BlankPage));If you’re using some container to create your view models, the NavigationService-instance can be registered into it as a singleton. If you’re using a simple ViewModelLocator without a container, the NavigationService can be added as a property to the App-class and it can be accessed when creating the view models. In either case, the NavigationService should be passed to the VM through the constructor, after which navigation from a view model is a straightforward task.
Here’s an example of a view model which uses the NavigationService to navigate forward to a new page:
public class BlankPageViewModel
{
private readonly NavigationService navigation;
public BlankPageViewModel(NavigationService navigation)
{
this.navigation = navigation;
}
public DelegateCommand GoToNextPage
{
get
{
return new DelegateCommand(x => navigation.Navigate<SecondPage>(), x => true);
}
}
}The BlankPageViewModel is constructed inside the ViewModelLocator-class:
public BlankPageViewModel BlankPageViewModel
{
get
{
return new BlankPageViewModel(App.NavigationService);
}
}A sample app containing two pages and the NavigationService-wrapper can be found from GitHub. The sample app also shows a basic implementation of the view model locator.