What is the best way to handle GoBack for the different MvvmCross (v3) platforms

Derek Beattie picture Derek Beattie · Apr 23, 2013 · Viewed 7.4k times · Source

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.

Answer

Stuart picture Stuart · Apr 23, 2013

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: