Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current ViewModel MvvmCross

Strangely, I did not find a direct answer to the very simple question on the internet.

How do I determine currently active ViewModel in MvvmCross runtime?

Is it possible? If not, why am I not supposed to do it?

like image 218
Aleksei Petrenko Avatar asked Dec 06 '22 02:12

Aleksei Petrenko


1 Answers

As I learned recently, which ViewModel is "active" depends heavily on which Presenter you use. If you just use the default presenters, it seems easy because only one ViewModel is shown at any given time. However, with more advanced presenters, you can have multiple active ViewModels.

Since the current active ViewModel(s) depends on which Presenter you are using (which lives in the view layer), Mvx core can't know how to access it/them. If this is something you think you need, I would recommend implementing your own Presenter with your own interface.

Here's an example for iOS:

ICurrentViewModelPresenter.cs

public interface ICurrentViewModelPresenter
{
    IMvxViewModel CurrentViewModel { get; }
}

CurrentViewModelPresenter.cs:

public class CurrentViewModelPresenter : MvxTouchViewPresenter, ICurrentViewModelPresenter
{
    public CurrentViewModelPresenter(UIApplicationDelegate del, UIWindow win)
        : base(del, win)
    {
    }

    public IMvxViewModel CurrentViewModel
    { 
        get
        {
            var viewController = MasterNavigationController.TopViewController;
            if (viewController == null) return null;

            var touchView = viewController as IMvxTouchView;
            if (touchView == null) return null;

            return touchView.ReflectionGetViewModel();
        }
    }
}

Setup.cs:

public class Setup : MvxTouchSetup
{
    private readonly MvxApplicationDelegate _del;
    private readonly UIWindow _win;

    public Setup(MvxApplicationDelegate del, UIWindow win)
        : base(del, win)
    {
        _del = del;
        _win = win;
    }

    ...

    protected override IMvxTouchViewPresenter CreatePresenter()
    {
        var presenter = new CurrentViewModelPresenter(_del, _win);

        Mvx.RegisterSingleton<ICurrentViewModelPresenter>(presenter);

        return presenter;
    }
}

Anywhere in your code:

var presenter = Mvx.Resolve<ICurrentViewModelPresenter>(); // or inject with IoC
var current = presenter.CurrentViewModel;

Note that exactly none of this was tested, but it should give you an idea of how it would work.

like image 179
chkimes Avatar answered Dec 10 '22 12:12

chkimes