Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can you explain how to use IMvxNavigationService to navigate between ViewModels


Can you explain how to use IMvxNavigationService to navigate between ViewModels


Using `IMvxNavigationService` in MvvmCross is a powerful way to navigate between ViewModels in a cross-platform application. Here's a detailed guide on how to use it effectively:

Introduction to IMvxNavigationService

`IMvxNavigationService` is an abstraction over native platform navigation, allowing you to navigate between ViewModels without worrying about the underlying Views. It provides a flexible and type-safe way to manage navigation in your application.

Basic Navigation

To navigate from one ViewModel to another, you can use the `Navigate` method provided by `IMvxNavigationService`. This method is asynchronous and type-safe, making it easy to implement navigation in your ViewModels.

csharp
public class MyViewModel : MvxViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public MyViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public async Task NavigateToNextViewModel()
    {
        await _navigationService.Navigate();
    }
}

In this example, `NextViewModel` is the target ViewModel to which you want to navigate. MvvmCross will automatically locate the corresponding View for `NextViewModel` and display it.

Navigation with Parameters

If you need to pass data from one ViewModel to another, you can use the `Navigate` method with a parameter. The target ViewModel must implement `IMvxViewModel` or inherit from `MvxViewModel`.

csharp
public class MyViewModel : MvxViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public MyViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public async Task NavigateToNextViewModelWithParameter(MyObject parameter)
    {
        await _navigationService.Navigate(parameter);
    }
}

public class NextViewModel : MvxViewModel
{
    private MyObject _myObject;

    public override void Prepare(MyObject parameter)
    {
        _myObject = parameter;
    }
}

In this example, `MyObject` is passed as a parameter to `NextViewModel`, which can then access it in its `Prepare` method.

Returning Results

If you need to return data from a ViewModel to the one that navigated to it, you can use `IMvxResultAwaitingViewModel` and `IMvxResultSettingViewModel`. This involves implementing interfaces in both the calling and the called ViewModels.

csharp
public class MyViewModel : MvxResultAwaitingViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public MyViewModel(IMvxNavigationService navigationService, IMvxResultViewModelManager resultViewModelManager)
        : base(resultViewModelManager)
    {
        _navigationService = navigationService;
    }

    public async Task NavigateToNextViewModelAndAwaitResult(MyObject parameter)
    {
        await _navigationService.NavigateRegisteringToResult(parameter, ResultViewModelManager);
    }

    public override bool ResultSet(IMvxResultSettingViewModel viewModel, MyReturnObject result)
    {
        if (viewModel is NextViewModel)
        {
            // Handle the result
            return true;
        }
        return false;
    }
}

public class NextViewModel : MvxResultSettingViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public NextViewModel(IMvxNavigationService navigationService, IMvxResultViewModelManager resultViewModelManager)
        : base(resultViewModelManager)
    {
        _navigationService = navigationService;
    }

    public async Task CloseAndReturnResult()
    {
        await _navigationService.CloseSettingResult(this, new MyReturnObject(), ResultViewModelManager);
    }
}

This setup allows `MyViewModel` to await a result from `NextViewModel` after navigating to it.

Checking Navigation Possibility

Before navigating to a ViewModel, you can check if navigation is possible using the `CanNavigate` method.

csharp
if (Mvx.IoCProvider.Resolve().CanNavigate())
{
    // Navigation is possible, proceed with navigation
}

Intercepting Navigation Events

You can also intercept navigation events such as `WillNavigate`, `DidNavigate`, `WillClose`, and `DidClose` by subscribing to these events on the `IMvxNavigationService`.

csharp
Mvx.IoCProvider.Resolve().DidNavigate += (sender, e) =>
{
    // Handle navigation event
};

This allows you to perform actions before or after navigation occurs.

In summary, `IMvxNavigationService` provides a robust and flexible way to manage navigation between ViewModels in MvvmCross applications, supporting parameter passing and result handling with ease.

Citations:
[1] https://www.mvvmcross.com/documentation/tutorials/tipcalc/the-tip-calc-navigation
[2] https://www.mvvmcross.com/documentation/fundamentals/view-presenters
[3] https://stackoverflow.com/questions/32518288/passing-data-between-viewmodels-mvvmcross
[4] https://www.mvvmcross.com/documentation/fundamentals/navigation
[5] https://stackoverflow.com/questions/51474717/mvvmcross-navigation-through-multiple-view-models
[6] https://www.reddit.com/r/androiddev/comments/1ecklee/using_multiple_view_models_for_different/
[7] https://yanxiaodi.gitbook.io/xamarin-mvvmcross-handbook/using-mvvmcross-to-create-your-first-xamarin-app/navigation/understanding-the-imvxnavigationservice
[8] https://github.com/MvvmCross/MvvmCross/issues/4032