Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon What is the role of IMvxResultViewModelManager in navigation


What is the role of IMvxResultViewModelManager in navigation


The `IMvxResultViewModelManager` plays a crucial role in navigation within MvvmCross, particularly when dealing with result-based navigation scenarios. This interface is part of the MvvmCross framework's navigation system, which allows view models to await results from other view models after navigating to them. Here's a detailed overview of its role and how it is used:

Overview of IMvxResultViewModelManager

`IMvxResultViewModelManager` is used in conjunction with two key interfaces: `IMvxResultAwaitingViewModel` and `IMvxResultSettingViewModel`. These interfaces enable view models to either await results from other view models or set results that can be retrieved by other view models.

Implementing IMvxResultAwaitingViewModel

To use `IMvxResultViewModelManager` for awaiting results, a view model must implement `IMvxResultAwaitingViewModel`. This involves the following steps:

1. Inheritance: The view model should inherit from `IMvxResultAwaitingViewModel`, where `TResult` is the type of result expected from another view model.

2. Constructor: The view model's constructor should accept an instance of `IMvxResultViewModelManager`, which is then stored in a protected property named `ResultViewModelManager`.

3. Reload and Save State: Override `ReloadFromBundle` and `SaveStateToBundle` methods to handle state management related to awaiting results. These methods ensure that the view model's state is properly saved and restored, especially when dealing with result-based navigation.

4. View Destruction: Override `ViewDestroy` to unregister the view model from awaiting results when it is closed.

Implementing IMvxResultSettingViewModel

For setting results, a view model should implement `IMvxResultSettingViewModel`. This involves:

1. Inheritance: Inheriting from `IMvxResultSettingViewModel`, where `TResult` is the type of result to be set.

2. Constructor: Similar to awaiting results, the constructor should accept an `IMvxResultViewModelManager` instance.

3. Setting Results: Implement a method to set the result using the `ResultViewModelManager`. This method allows the view model to notify other view models that are awaiting results.

Role in Navigation

The `IMvxResultViewModelManager` facilitates decoupled communication between view models during navigation. It allows one view model to navigate to another and await a result without tightly coupling the two view models. This is particularly useful in scenarios where a view model needs to retrieve data or a selection from another view model, such as selecting a value from a list.

By using `IMvxResultViewModelManager`, developers can implement robust navigation flows where view models can request and receive results asynchronously, enhancing the overall flexibility and maintainability of the application's architecture.

Example Usage

Here's a simplified example of how `IMvxResultViewModelManager` might be used in a view model that awaits a result:

csharp
public class MyAwaitingViewModel : MvxViewModel, IMvxResultAwaitingViewModel
{
    protected IMvxResultViewModelManager ResultViewModelManager { get; }

    public MyAwaitingViewModel(IMvxResultViewModelManager resultViewModelManager)
    {
        ResultViewModelManager = resultViewModelManager;
    }

    protected override void ReloadFromBundle(IMvxBundle state)
    {
        base.ReloadFromBundle(state);
        ReloadAndRegisterToResult(state, ResultViewModelManager);
    }

    protected override void SaveStateToBundle(IMvxBundle bundle)
    {
        base.SaveStateToBundle(bundle);
        SaveRegisterToResult(bundle, ResultViewModelManager);
    }

    public override void ViewDestroy(bool viewFinishing = true)
    {
        base.ViewDestroy();
        if (viewFinishing)
            UnregisterToResult(ResultViewModelManager);
    }
}

And here's how another view model might set a result:

csharp
public class MySettingViewModel : MvxViewModel, IMvxResultSettingViewModel
{
    protected IMvxResultViewModelManager ResultViewModelManager { get; }

    public MySettingViewModel(IMvxResultViewModelManager resultViewModelManager)
    {
        ResultViewModelManager = resultViewModelManager;
    }

    public virtual void SetResult(string result)
    {
        SetResult(result, ResultViewModelManager);
    }
}

This setup allows `MyAwaitingViewModel` to navigate to `MySettingViewModel`, await a string result, and receive it without needing to know the specifics of how `MySettingViewModel` operates.

Citations:
[1] https://www.mvvmcross.com/documentation/fundamentals/navigation
[2] https://stackoverflow.com/questions/5421874/basic-concepts-of-mvvm-what-should-a-viewmodel-do
[3] https://support.microsoft.com/en-us/office/use-the-navigation-pane-274dfc5a-281b-472b-94e2-ef931c5cc590
[4] https://stackoverflow.com/questions/43727635/in-mvvmcross-is-it-possible-to-close-a-viewmodel-and-pass-values-back-to-the-pr
[5] https://learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm
[6] https://app.pope.tech/result-documentation/articles/layout-table
[7] https://github.com/MvvmCross/MvvmCross/issues/1634
[8] https://www.youtube.com/watch?v=ve0DFu-arD8