In MvvmCross v3 I use ShowViewModel
to navigate to different pages. Before converting over to Mvx I'd use the NavigationService.GoBack()
method to go back to the previous page. The advantage being that the page isn't re-created.
Since the GoBack
method is platform specific to WP, WInRT, Silverlight, what is the best way to handle returning to the previous page so the view model remains platform independent?
One solution might be to use ShowViewModel
passing some data that the view can see and then in the case of WP/WinRT, calling RemoveBackEntry
from the view. But with Mvx, there's probably a better way.
In MvvmCross v3, we provided a specific mechanism to allow ViewModels to send messages to the UI that they would like to change the current presentation.
This mechanism is
ChangePresentation(MvxPresentationHint hint)
and it provides routing of messages - presentation hints - fromViewModels
to thePresenter
.How the
Presenter
handles these messages is platform and application specific.This message mechanism is very general and it might be used for all sort of things in the future - e.g. devs might supply hints which do things like change the UI layout, which highlight part of the UI, which force the user focus on to a certain control, which cause the SIP to be displayed or hidden, etc.
For the case of closing a view model, we have provided a specialisation of
MvxPresentationHint
-MvxClosePresentationHint
- and a helper method in a base class ofMvxViewModel
:To use this a ViewModel can just call
Close(this)
When this is called, the Presenter within your UI will receive a message on the
ChangePresentation
method:For the general/typical case - where the
ViewModel
that is being closed is attached to the view which is the topmostActivity
/Page
/UIViewController
, the default presenters within MvvmCross will be able to handle this message and will be able toGoBack
in Windows, toFinish
in Android, and toPopViewController
in iOS.However, if your UI is more complicated than that - e.g. if the
ViewModel
you want toClose
actually corresponds to aTab
, to aFlyout
, to aSplitView
pane, etc, or if theViewModel
corresponds to something other than the current topmost view in the hierarchy - then you will need to provide a custom presenter implementation - and that implementation will have to do platform and application specific logic to handle theClose
.The above hint is what I recommend you use...
However, as an alternative:
If you were to feel this
ChangePresentation(MvxPresentationHint hint)
mechanism was simply too heavyweight/overkill for your app, then you can also, of course, drop down to a custom orMessage
based mechanism instead.One sample that does this is the CustomerManagement sample - it provides a custom IViewModelCloser implementation on each platform - see:
I'm not completely sure about mvvmcross, but in MVVM Light what is usually done is to create an INavigationService interface that exposes these methods.
Then, each platform implements this Interface in the platform-specific way (in WP for example by getting a reference to the current frame and its content). This platform specific instance can then do all the correct actions to make sure the navigation pattern is correctly implemented.
Your ViewModels can then get a reference to an instance of the INavigationService through a Dependency Container. That way your VM is independent on the platform specifics of navigation.
I also wrote a blog post on how to use Interfaces to expose a common API for platform specific features: http://www.kenneth-truyers.net/2013/02/24/patterns-for-sharing-code-in-windows-phone-and-windows-8-applications/
The example in the blog post is about Isolated Storage, but the same principles apply to Navigation (or any feature that has different implementations on various platforms for that matter)