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 - from ViewModels
to the Presenter
.
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 of MvxViewModel
:
protected bool Close(IMvxViewModel viewModel)
{
return ChangePresentation(new MvxClosePresentationHint(viewModel));
}
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:
public interface IMvxViewPresenter
{
void Show(MvxViewModelRequest request);
void ChangePresentation(MvxPresentationHint hint);
}
For the general/typical case - where the ViewModel
that is being closed is attached to the view which is the topmost Activity
/Page
/UIViewController
, the default presenters within MvvmCross will be able to handle this message and will be able to GoBack
in Windows, to Finish
in Android, and to PopViewController
in iOS.
However, if your UI is more complicated than that - e.g. if the ViewModel
you want to Close
actually corresponds to a Tab
, to a Flyout
, to a SplitView
pane, etc, or if the ViewModel
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 the Close
.
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 or Message
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With