June 24, 2015 // By Brent Edwards
This is the second part in a 5 part series. In the first part, we looked at Xamarin.Forms and why you should consider using MvvmCross for your cross-platform apps. We also created a Xamarin.Forms solution and started getting it ready for integration with MvvmCross. In this part, we will look at what it takes to integrate MvvmCross into your Xamarin.Forms solution.
We’re picking up where Part 1 left off, so open up the solution you started and let’s do this.
- Add MvvmCross Nuget package to each client project. Also add it to the portable project, if applicable.
- Right-click solution > Manage Nuget packages
- Search for MvvmCross
- Press Install
- Select projects
In the Android project:
- Delete the MainActivity class
- Delete the Views folder
- Delete the ToDo-MvvmCross folder
In the Portable or Shared project
- Rename the App class to something specific to project. I'll call it CoreApp.
- This avoids confusion with other App classes, especially once Windows is involved.
public class CoreApp : Application { // Contents removed for brevity }
In the Android project
- Change the reference in Setup.CreateApp to the renamed CoreApp class from step 14.
protected override IMvxApplication CreateApp() { return new CoreApp(); }
In the iOS project:
- Change the reference in Setup.CreateApp to the renamed CoreApp class from step 14.
protected override IMvxApplication CreateApp() { return new CoreApp(); }
In the WinPhone project:
- Change the reference in Setup.CreateApp to the renamed CoreApp class from step 14.
protected override IMvxApplication CreateApp() { return new CoreApp(); }
- In MainPage.xaml.cs, comment out the LoadApplication call for now.
- Change MainPage to inherit from PhoneApplicationPage, both the XAML and the codebehind.
public partial class MainPage : PhoneApplicationPage { public MainPage () { // Extra stuff removed //LoadApplication (new XFormsCrossTemplate.UI.CoreApp ()); } } <phone:PhoneApplicationPage xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" …> </phone:PhoneApplicationPage>
In the Portable or Shared project
- Add a Views folder
- Note: If you have separate projects for your views and view models, this would go into the views project.
- Add the first page as a Forms XAML page to the Views folder. I’ll call it FirstPage.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="XFormsCrossTemplate.UI.Views.FirstPage"> <Label Text="First Page" VerticalOptions="Center" HorizontalOptions="Center" /> </ContentPage>
- Add a ViewModels folder
- Note: If you have separate projects for your views and view models, this would go into the views project.
- Add a BaseViewModel abstract class to ViewModels folder, inheriting from MvvmCross’s MvxViewModel. All other view models will inherit from this.
public abstract class BaseViewModel : MvxViewModel { }
- Add a view model for first page, inheriting from BaseViewModel. I’ll call it FirstPageViewModel.
public class FirstPageViewModel : BaseViewModel { }
- Change CoreApp to inherit from MvxApplication.
- Add the following Initialize method to register all view models with the IoC container and register FirstPageViewModel as the AppStart.
public class CoreApp : MvxApplication { public override void Initialize() { CreatableTypes() .EndingWith("ViewModel") .AsTypes() .RegisterAsDynamic(); RegisterAppStart<FirstPageViewModel>(); } }
- Add a Helpers folder
- Add Helpers/MvxPresenterHelpers class
- This is a good starting point: https://github.com/Cheesebaron/Xam.Forms.Mvx/blob/master/Movies/Movies/MvxPresenterHelpers.cs
- This will create a view/viewmodel naming scheme that follows the pattern: FirstPage/FirstPageViewModel.
public static class MvxPresenterHelpers { public static IMvxViewModel LoadViewModel(MvxViewModelRequest request) { var viewModelLoader = Mvx.Resolve<IMvxViewModelLoader>(); var viewModel = viewModelLoader.LoadViewModel(request, null); return viewModel; } public static T CreatePage<T>(MvxViewModelRequest request) where T : class { var viewType = MvxPresenterHelpers.ResolveViewType( request.ViewModelType); if (viewType == null) { Mvx.Trace("Page not found for {0}", request.ViewModelType.Name); return null; } var page = Activator.CreateInstance(viewType) as T; if (page == null) { Mvx.Error("Failed to create ContentPage {0}", viewType.Name); } return page; } private static Type ResolveViewType(Type viewModelType) { var viewName = viewModelType.AssemblyQualifiedName.Replace( viewModelType.Name, viewModelType.Name.Replace("ViewModel", string.Empty)); viewName = viewName.Replace("Model", string.Empty); Type viewType = null; if (Device.Idiom == TargetIdiom.Tablet) { viewType = Type.GetType( viewName.Replace("Page", "PageTablet")); } else { viewType = Type.GetType( viewName.Replace("Page", "PagePhone")); } if (viewType == null) { viewType = Type.GetType(viewName); } return viewType; } }
That's it for general integration of MvvmCross into your Xamarin.Forms solution. But we’re not done yet. In the next part, we’ll look at what it takes to get the Android app up and running.
You’ve just read part 2 of the “Comprehensive Guide to Creating a Xamarin.Forms App with MvvmCross” blog series. To read part 3, click here. If you’d like to contact Magenic, email us or call us at 877-277-1044.