2
votes

I am trying to override the default view model association but having no luck so far. I need to override this default behavior because some of my ViewModels do not follow the name convention assumed by the default view model lookup. For example, I have some ViewModels in namespace Pidac.Core.ViewModels, while the Views are defined in MyApplication.Droid.Views.

I have tried the option to provide an explicity type mapping in Setup.cs of the Droid project as follows:

 protected override void InitializeViewLookup()
        {
            var viewModelViewLookup = new Dictionary<Type, Type>()
            {
                  { typeof (FirstViewModel), typeof(FirstView) },     
                  { typeof (FloatSettingViewModel), typeof(FloatSettingView) },
                  { typeof (SettingsViewModel), typeof(SettingsView) },
                  { typeof (SearchResultDialogViewModel), typeof(SearchResultDialogView) },
            };

            var container = Mvx.Resolve<IMvxViewsContainer>();
            container.AddAll(viewModelViewLookup);      
        }

With this, my application no longer goes past the MvvmCross logo screen.

Alternately, I tried providing the concrete view model type within FloatSettingView.cs as follows:

[Activity(Label = "settings", Theme = "@android:style/Theme.NoTitleBar")]
    public class FloatSettingView : MvxActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.FloatSettingView);
        }

        public new FloatSettingViewModel ViewModel
        {
            get { return base.ViewModel as FloatSettingViewModel; }
            set { base.ViewModel = value; }
        }
    }

Using only this second approach, without providing a view model to view type mapping in Setup.cs, I get an exception when the framework attempts to load FloatSettingView. Exception is Failed to find viewmodel for Pidac.Core.ViewModels.FloatSettingViewModel.

I tried the third option of decorating my view with the MvxViewForAttribute as follows:

 [Activity(Label = "settings", Theme = "@android:style/Theme.NoTitleBar")]
[MvxViewFor(typeof(FloatSettingViewModel))]
        public class FloatSettingView : MvxActivity
        {
            protected override void OnCreate(Bundle bundle)
            {
                base.OnCreate(bundle);
                SetContentView(Resource.Layout.FloatSettingView);
            } 

        }

with no luck. I am obviously overlooking something here. Before I dig into the source, has anyone done this before?

TIA.

1
'Failed to find viewmodel' suggests the problem is with the view model lookup - is your app.cs in the same assembly as your view models? If not, try overriding GetVirwModelAssemblies in Setup. Stuart (away from home on mobile - so no proper answers) - Stuart
Stuart, that was it thanks. App.cs is not in the same assemblies as some of these ViewModels. Overriding GetViewModelAssemblies in Setup is all I had to do. Did not need any of the aforementioned. Thanks again. - Klaus Nji
Can you explain how you overrode GetViewModelAssemblies? - Chase Florell
@ChaseFlorell, GetViewModelAssemblies is a protected virtual method defined in MvxSetup. Override this in the Setup class defined in Setup.cs found in the root of the corresponding platform's project. For Android, Setup.cs derives from MvxAndroidDialogSetup. - Klaus Nji

1 Answers

1
votes

You should call base.InitializeViewLookup() when overriding, so you can get past the splash screen.