As shown in my last post, a MvxViewModelRequest
contains a dictionary named PresentationValues
that can be very useful in passing around data that your presenter might find useful. Let's say you that in your view model you know that when you request to show a view model you know that you want to clear the app's back stack before showing it, such as after a login operation so that the login screen is no longer in the stack.
All overloads of ShowViewModel()
in MvvmCross contain an optional IMvxBundle
parameter named presentationBundle
. It's easy to create a bundle from a dictionary and then pass that into the show request:
var presentationBundle = new MvxBundle(new Dictionary<string, string> { { "NavigationMode", "ClearStack" } });
ShowViewModel<MyViewModelType>(presentationBundle: presentationBundle);
When your platform's presenter gets that request, the values you passed in with the presentation bundle will be available in the PresentationValues
property described earlier. With that in place, let's implement the clear operation on both iOS and Android.
iOS
For this example I'm going to assume the presenter inherits from the standard MvxTouchViewPresenter
class provided in MvvmCross, which manages a UINavigationController
stored in a property named MasterNavigationController
. All our presenter needs to do is detect the hint we sent in the request and react accordingly:
public override void Show(MvxViewModelRequest request)
{
if (request.PresentationValues != null)
{
if (request.PresentationValues.ContainsKey("NavigationMode") && request.PresentationValues["NavigationMode"] == "ClearStack")
MasterNavigationController.PopToRootViewController(false);
}
base.Show(request);
}
I'm using magic strings here to keep things simple, but you could use constants/enums/whatever works for your application if you want to formalize things a bit more. The false
sent in to PopToRootViewController()
says not to animate so that it happens immediately. You can easily get yourself into trouble with UINavigationController
if you have competing navigations, so definitely be careful there. I'll dig into that topic further in a future post.
Android
Now let's look at Android. I'm going to assume a presenter that's using fragments for all views and has a FragmentManager
field it uses to manage them. In a future post I'll talk in more detail on how to implement this model in Android, but that's a bit off topic here. With that aside, the Android implementation ends up looking pretty similar to iOS:
public override void Show(MvxViewModelRequest request)
{
if (vmRequest.PresentationValues != null)
{
if (request.PresentationValues.ContainsKey("NavigationMode") && request.PresentationValues["NavigationMode"] == "ClearStack")
_fragmentManager.PopBackStackImmediate(null, PopBackStackFlags.Inclusive);
}
// ...
}
This is just one thing you can do with presentation values, so it's really up to you and what makes sense in your apps. If you have some knowledge in your view models that are of use to the presenter during a request, these values provide an easy way to pass that knowledge along with it.