henda79
henda79

Reputation: 535

MVVMCross How to get ViewModel Instance within View Code Behind

I'm using MVVMCross 7.1.2 and have a situation where several of my pages can't inherit the MvxContentPage class. Understandably this breaks a few things that MVVMCross implements.

One thing I noticed is the BindingContext for the page does not get set and as a result we get a NullReference exception which is difficult to debug.

What is the best was to access the ViewModel Instance form the Views code behind ? At the moment I'm using the interface IMvxOverridePresentationAttribute and then implementing it like this:

public MvxBasePresentationAttribute PresentationAttribute(MvxViewModelRequest request)
{
    BindingContext = ((MvxViewModelInstanceRequest) request).ViewModelInstance;
    InitializeComponent(); <--- Update 1,moved from ctor
    return null;
}

Is this the best way to get the VM instance ? or is there a better to the BindingContext automatically set.

UPDATE 1; I still get the NullReference Exception with this method presumably as it sets the BindingContext after InitializeComponent is called. I've tried moving the InitializeComponent call to after the BindingContext is set but the page doesn't render correctly.

Upvotes: 2

Views: 1258

Answers (1)

tuke307
tuke307

Reputation: 430

Have you tried something like this?

public partial class SomeView : ContenPage
{
    public ViewModels.NestedViewModel ViewModel {get; set;}

    public SomeView()
    {
         InitializeComponent();
    
        // when viewmodel already created
        if (Mvx.IoCProvider.TryResolve<ViewModels.NestedViewModel>(out var someViewModel))
        {
             ViewModel = someViewModel;
             BindingContext = ViewModel;
             return;
        }

        // creating viewmodel
        var _viewModelLoader = Mvx.IoCProvider.Resolve<IMvxViewModelLoader>();
        var request = new MvxViewModelInstanceRequest(typeof(ViewModels.NestedViewModel));
        request.ViewModelInstance = _viewModelLoader.LoadViewModel(request, null);
        ViewModel = request.ViewModelInstance as ViewModels.NestedViewModel;
        BindingContext = ViewModel;

        Mvx.IoCProvider.RegisterSingleton<ViewModels.NestedViewModel>(ViewModel);
    }
}

Upvotes: 3

Related Questions