Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In MVVMCross, is it possible to close a viewmodel and pass values back to the previous viewmodel in the navigation stack?

Consider the following example. I have three view models, ViewModel_A, ViewModel_B, and ViewModel_Values.

I want to be able to navigate to ViewModel_Values from either ViewModel_A or ViewModel_B, select a value from ViewModel_Values, then return that value to the calling view model.

Is there a way of passing arguments to previous view models in the navigation stack so that I can simply call ViewModel_Values.Close(this), thereby ensuring that the ViewModels_Values is decoupled from any other view models and can be used with arbitrary "parent" view models?

like image 999
GabeFC Avatar asked May 01 '17 22:05

GabeFC


2 Answers

MvvmCross 5 onwards

From MvvmCross 5 you can use the new IMvxNavigationService that allows you to have a much richer navigation. One of the new features is the possibility to await a value from another ViewModel after navigating to it and should be the approach to take after MvvmCross 5 instead of Messenger, e.g.:

public class ViewModel_A : MvxViewModel
{
    private readonly IMvxNavigationService _navigationService;
    public ViewModel_A(IMvxNavigationService navigation)
    {
        _navigationService = navigationService;
    }

    public override async Task Initialize()
    {
        //Do heavy work and data loading here
    }

    public async Task SomeMethod()
    {
        var result = await _navigationService.Navigate<ViewModel_Values, MyObject, MyReturnObject>(new MyObject());
        //Do something with the result MyReturnObject that you get back
    }
}

public class ViewModel_Values : MvxViewModel<MyObject, MyReturnObject>
{
    private readonly IMvxNavigationService _navigationService;
    public ViewModel_Values(IMvxNavigationService navigation)
    {
        _navigationService = navigationService;
    }

    public override void Prepare(MyObject parameter)
    {
        //Do anything before navigating to the view
        //Save the parameter to a property if you want to use it later
    }

    public override async Task Initialize()
    {
        //Do heavy work and data loading here
    }

    public async Task SomeMethodToClose()
    {
        // here you returned the value
        await _navigationService.Close(this, new MyReturnObject());
    }
}

More info here HIH

like image 120
fmaccaroni Avatar answered Nov 18 '22 14:11

fmaccaroni


Use messaging center. Here is the sample code.

//for trigger
MessagingCenter.Send<object> (this, "Hi");

//put this where you want to receive your data
MessagingCenter.Subscribe<object> (this, "Hi", (sender) => {
    // do something whenever the "Hi" message is sent
});
like image 24
Edrian Dragneel Avatar answered Nov 18 '22 14:11

Edrian Dragneel