MvvmCross: Does ShowViewModel always construct new instances?
Asked Answered
M

2

6

Whenever I call ShowViewModel, somehow a ViewModel and a View of the requested types are retrieved and are bound together for display on the screen. When are new instances of the ViewModel and View created versus looked up and retrieved from a cache somewhere? If new instances are always created and I choose to make my own cache to prevent multiple instances, then how do I show my cached ViewModel instance?

Mennonite answered 23/5, 2013 at 20:14 Comment(0)
A
7

When are new instances of the ViewModel and View created versus looked up and retrieved from a cache somewhere?

Never - for new navigations the default behaviour is always to create new instances.

if... how do I show my cached ViewModel instance?

If for whatever reason you want to override the ViewModel location/creation, then there's information available about overriding the DefaultViewModelLocator in your App.cs in:

Put simply, implement your code:

public class MyViewModelLocator
  : MvxDefaultViewModelLocator
{
    public override bool TryLoad(Type viewModelType, IDictionary<string, string> parameterValueLookup,
                             out IMvxViewModel model)
    {
        // your implementation
    }
}

then return it in App.cs:

protected override IMvxViewModelLocator CreateDefaultViewModelLocator()
{
    return new MyViewModelLocator();
}

Note that older posts like How to replace MvxDefaultViewModelLocator in MVVMCross application are still conceptually compatible - but the details in those older posts are now out of date.

Abidjan answered 23/5, 2013 at 20:37 Comment(1)
Just to note that in my experience using my WP8 device and MvvmCross v3, each navigation (new or not new) resulted with new ctor for the ViewModel. I confirmed the same behavior with N-05-MultiPage tutorial code. please refer to this SO question for more information.Colour
F
4

In MvvmCross v3.5 you can use this Class:

public class CacheableViewModelLocator : MvxDefaultViewModelLocator{
public override IMvxViewModel Load(Type viewModelType, IMvxBundle parameterValues, IMvxBundle savedState)
{
    if (viewModelType.GetInterfaces().Any(x=>x == typeof(ICacheableViewModel)))
    {
        var cache = Mvx.Resolve<IMvxMultipleViewModelCache>();
        var cachedViewModel = cache.GetAndClear(viewModelType);

        if (cachedViewModel == null)
            cachedViewModel = base.Load(viewModelType, parameterValues, savedState);

        cache.Cache(cachedViewModel);

        return cachedViewModel;
    }

    return base.Load(viewModelType, parameterValues, savedState);
}}

in your App Code override this method:

protected override IMvxViewModelLocator CreateDefaultViewModelLocator(){
return new CacheableViewModelLocator();}

Create an interface "ICacheableViewModel" and implement it on your ViewModel.

Now you can share the same ViewModel instance with multiple Views.

Feverous answered 25/2, 2015 at 17:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.