The default convention used by the MvvmCross platform is to automatically register all views using reflection.
This is done in the base Setup class - inhttps://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Platform/MvxBaseSetup.cs:
protected virtual void InitializeViews()
{
var container = this.GetService();
foreach (var pair in GetViewModelViewLookup())
{
Add(container, pair.Key, pair.Value);
}
}
where
GetViewModelViewLookup
returns a dictionary of ViewModel type to View type: protected virtual IDictionary GetViewModelViewLookup(Assembly assembly, Type expectedInterfaceType)
{
var views = from type in assembly.GetTypes()
let viewModelType = GetViewModelTypeMappingIfPresent(type, expectedInterfaceType)
where viewModelType != null
select new { type, viewModelType };
return views.ToDictionary(x => x.viewModelType, x => x.type);
}
In universal iPad/iPhone apps you do occasionally want to include multiple views for each viewmodel - using one view in the iPad and one view in the iPhone.
To do this, there are now (literally just now!) some attributes available to mark your views as being "unconventional" - these are:
- MvxUnconventionalViewAttribute
- use this to mark that your view should never be included by convention
- inhttps://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Views/Attributes/MvxUnconventionalViewAttribute.cs
- MvxConditionalConventionalViewAttribute
- an abstract attribute - override this to provide your own custom logic for inclusion/exclusion
- inhttps://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Views/Attributes/MvxConditionalConventionalViewAttribute.cs
- MvxFormFactorSpecificViewAttribute
- iOS/Touch only
- an attribute that will include the view if and only if the detected iPhone form factor matches the current device
- inhttps://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Touch/Views/Attributes/MvxFormFactorSpecificViewAttribute.cs
The last of these is probably what you want in this case - you could implement simple iPhone/iPad switching for a MainViewModel using two views declared like:
[MvxFormFactorSpecificView(MvxTouchFormFactor.Phone)]
public class MyIPhoneView : BaseView
{
// iphone specific view ...
}
[MvxFormFactorSpecificView(MvxTouchFormFactor.Pad)]
public class MyIPadView : BaseView
{
// ipad specific view ...
}
Alternatively if you want a very custom configuration, you can override all 'convention-based' behaviour - you can implement your own override of
GetViewModelViewLookup
- e.g.:protected override IDictionary GetViewModelViewLookup(Assembly assembly, Type expectedInterfaceType)
{
if (IsIPad)
{
return new Dictionary()
{
{ typeof(HomeViewModel), typeof(IPadHomeView) },
{ typeof(DetailViewModel), typeof(IPadDetailView) },
{ typeof(AboutViewModel), typeof(SharedAboutView) },
};
}
else
{
return new Dictionary()
{
{ typeof(HomeViewModel), typeof(IPhoneHomeView) },
{ typeof(DetailViewModel), typeof(IPhoneDetailView) },
{ typeof(AboutViewModel), typeof(SharedAboutView) },
};
}
}
Note that eventually you may decide that you need additional ViewModels as well as Views for the iPad app - the iPad has, after all, a much bigger screen - in this case you can add them manually. Ultimately, when your app hits a few million users, you may even decide to completely branch the tablet code away from the phone code - but that can generally wait until you hit that few million mark...
No comments:
Post a Comment