Sunday, December 30, 2012

A quick start on creating an mvvmcross application

MvvmCross (Mvx) is very modular in design.

It's deliberately made up of lots of small assemblies rather than a few big ones.

The advantages of this are that it keeps the runtime image size smaller, and that it makes the platform more easily extensible.

The disadvantages, however, are that it can make mvvmcross look a little complicated initially, and that adding 'using' namespace statements in code can feel a bit more awkward, especially in environments where tools like resharper are not available.

One other thing to note: PCL support in the MonoDevelop tools is particularly 'alpha' still right now - so you may find you need to implement 'workarounds' like only using PCLs built in MonoTouch for use on MonoTouch. This situation is slowly improving... but in the meantime, sorry!

This article provides a QuickStart on creating an MvvmCross application.

If this is too shallow, then maybe try the more in-depth guide - http://slodge.blogspot.com/2012/12/a-guide-to-mvvmcross-assemblies.html



A QuickStart...


Before you start - get your development environment ready for Portable Class Libraries - see http://slodge.blogspot.co.uk/2012/12/cross-platform-winrt-monodroid.html



Core

Create a typical mvvmcross 'core' application:
  • Create a PCL project - named MyApp.Core - make sure it is in the magic 'Profile104'
  • Add a reference to the assembly - Cirrious.MvvmCross.dll
  • Add a 'main' App.cs which will own the Services, ViewModels and other classes in the application.
  • Add a Trace.cs file - so that your application trace is easily identifiable.
  • Add a StartupApplicationObject.cs class - which identifies which ViewModel will be shown on app startup.
  • Add a ViewModels folder.
  • In this folder, place BaseViewModel.cs, derived from MvxViewModel
  • In this folder, place HomeViewModel.cs, derived from BaseViewModel
This will give you a set of files something like:




A WindowsPhone UI

To add a windows phone UI:
  • Create a WindowsPhone App project - named MyApp.UI.WinPhone
  • Target 7.1 or 8.0 (or later?!) according to your preferences
  • Add a reference to the portable Cirrious.MvvmCross.dll, Cirrious.Plugins.Json.dll and Newtonsoft.Json.dll
  • Add a reference to Cirrious.MvvmCross.WindowsPhone.dll
  • Add a reference to the Core project in your solution
  • Change the App.xaml.cs file so that App inherits from

    IMvxServiceConsumer
    
    
  • Change the end of the App.xaml.cs constructor so that it creates a Setup object:
            var setup = new Setup(RootFrame);
            setup.Initialize();
  • Change the App.xaml.cs file so that ApplicationLaunching looks like:
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {
            RootFrame.Navigating += RootFrameOnNavigating;
        }
 
        private void RootFrameOnNavigating(object sender, NavigatingCancelEventArgs navigatingCancelEventArgs)
        {
            RootFrame.Navigating -= RootFrameOnNavigating;
            navigatingCancelEventArgs.Cancel = true;
            RootFrame.Dispatcher.BeginInvoke(() =>
                                                 {
                                                     var start = this.GetService<IMvxStartNavigation>();
                                                     start.Start();
                                                 });
        } 
  
  • note that for this code to compile, then you will need to add using statements for:
using Cirrious.MvvmCross.ExtensionMethods;
using Cirrious.MvvmCross.Interfaces.ServiceProvider;
using Cirrious.MvvmCross.Interfaces.ViewModels;
  • add a Setup.cs file:

  • add a Views folder
  • create a new page in the Views folder - call it HomeView.xaml
  • change the HomeView.xaml.cs file so that it inherits from a BaseHomeView class which in turn inherits from MvxPhonePage

  • change HomeView.xaml similarly - so that the page inherits from BaseHomeView



A Droid UI

Note: If you haven't already done so, set up your MonoDroid PCL environment - see http://slodge.blogspot.co.uk/2012/12/cross-platform-winrt-monodroid.html

To add a MonoDroid UI:

  • Create a new MonoDroid App project - name it MyApp.UI.Droid
  • Add a reference to the portable Cirrious.MvvmCross.dll, Cirrious.MvvmCross.Binding.dll and NewtonSoft.Json.dll
  • Add a reference to the android specific libraries of Cirrious.MvvmCross.Droid.dll, Cirrious.MvvmCross.Binding.Android.dll, System.Net.dll and System.Windows.dll
  • Add a reference to the Core project in your solution
  • Delete the Activity1.cs file 
  • Add a copy of the MvxBindingAttributes file in Resources/Values folder - from https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/ResourcesToCopy/MvxBindingAttributes.xml - make sure this is marked as an AndroidResource
  • Add a Setup.cs file a bit like:

  • Add a SplashScreen activity and /Resources/Layout/SplashScreen.axml file like:

  • Add a Views folder
  • In the Views folder and in the Resources Layout folder, add a HomeView like



An iOS UI

Note: On the Mac to target iOS, you need a different set of MvvmCross binaries - in the release folders on http://slodge.blogspot.co.uk/p/mvvmcross-binaries_7.html you will generally find 2 sets of binaries - one for using with VS for Droid/RT/WPF/etc and one for MD on the Mac for iOS.

Note: If you haven't already done: You must edit your targets file. See here: http://slodge.blogspot.co.uk/2013/01/if-pcls-will-not-build-for-you-in.html

To add a MonoTouch UI:
  • Create a new MonoTouch App project - name it MyApp.UI.Touch
  • Add a reference to the portable Cirrious.MvvmCross.dll, Cirrious.MvvmCross.Binding.dll and Newtonsoft.Json.dll
  • Add a reference to the Touch specific libraries of Cirrious.MvvmCross.Touch.dll, Cirrious.MvvmCross.Binding.Touch.dll, System.Net.dll and System.Windows.dll
  • Add a reference to the Core project in your solution.
  • Add a Setup.cs file a bit like:

  • Change your AppDelegate.cs so that it looks like:

  • Add a Views folder:
  • In the Views folder, add a HomeView using the XIB UIViewController option, but then modify the view controller's inheritance and constructor like:



A WinRT UI

To add a Windows RT UI:

  • Add a new Windows Store project - Casino.UI.WinRT
  • Add a reference to the portable Cirrious.MvvmCross.dll, Cirrious.MvvmCross.Plugin.Json.dll and NewtonSoft.Json.dll
  • Add a reference to the WinRT specific libraries of Cirrious.MvvmCross.WinRT.dll, Cirrious.
  • Add a reference to the Core project in your solution
  • Add a file for Setup.cs like:

  • Modify the App.xaml.cs file to provide setup initialisation like:

  • Add a Views folder:
  • In the Views folder, add a HomeView like:

  • In the Common Files folder, edit the LayoutAwarePage.cs file:
    • Change it so that it inherits from
      Cirrious.MvvmCross.WinRT.Views.MvxWinRTPage
      
    • Change the OnNavigatedTo method so that it calls the base method
      base.OnNavigatedTo(e); 
    • Change the OnNavigatedFrom method so that it calls the base method
      base.OnNavigatedFrom(e); 



A WPF UI

To add a WPF UI:

  • Add a new WPF project - Casino.UI.Wpf
  • Add a reference to the portable Cirrious.MvvmCross.dll, Cirrious.MvvmCross.Plugin.Json.dll and NewtonSoft.Json.dll
  • Add a reference to the Wpf specific library of Cirrious.MvvmCross.Wpf.dll
  • Add a reference to the Core project in your solution
  • Add files for Setup.cs, SimplePresenter.cs, and Program.cs
  • Modify the App.xaml.cs and MainWindow.Xaml.* files

  • Add a Views folder
  • In the Views folder and add a HomeView using 'New User Control' to produce a file like:

  • Because we have added an extra Main to our project, go to project properties in Visual Studio and modify the startup application in the Application tab. Set the startup object to Casino.UI.Wpf.Program

1 comment:

  1. Thanks for this great entry point to MvvmCross!

    This guide helped to get started with your framework on all platforms I`d like to develop for.

    I walked into some issues setting up these projects. The following lines are maybe useful to all beginners.

    First of all: Download the MvvmCross binaries from http://slodge.blogspot.co.uk/p/mvvmcross-binaries_7.html
    I completed this guide with the binaries from 2013_01_28.

    My issues:

    1 [WindowsPhone]
    IMvxServiceConsumer is deprecated. Use ImvxServiceConsumer instead.

    2 [WindowsPhone]
    To change the base class of WP page, you must change the root element of the xaml to
    "local:BaseHomeView"

    and add the namespace
    xmlns:local="clr-namespace:Casino.UI.WP7.Views"

    For more information see http://blogs.msdn.com/b/jschaffe/archive/2011/03/03/creating-a-custom-base-page-for-windows-phone-7.aspx

    3 [WindowsPhone]
    I got compilation errors after changing the base class of a WP page before I installed Service Pack 1 for Visual Studio 2012.

    4 [Android]
    Do not create a SplashScreen.xml. Create a SplashScreen.axml instead and save it into the Resources\Layout folder.

    5 [iOS]
    I'm not sure whether it's a bug or an incorrect configuration on my Mac but I got compile errors before I switched all references to the binaries in BuiltInMonoTouch\Touch\Release. Debug binaries or anything in the Protable folder doesn't work for me.

    6 [iOS]
    If you haven't already done: You must edit your targets file. See here: http://slodge.blogspot.co.uk/2013/01/if-pcls-will-not-build-for-you-in.html

    7 [iOS]
    I received SIGABRT error on startup and an exception saying "HomeView" could not be loaded.
    I found to ways to solve this problem. For both ways you have to change the base constructer call in the HomeView class.
    First: public HomeView (MvxShowViewModelRequest request) : base(request) // This results in an empty page with the typical blue header bar
    Second: public HomeView (MvxShowViewModelRequest request) : base(request, "HomeView_iPhone", null) // This works after you created XIB files for this view in Xcode.

    8 [Wpf]
    Don't be afraid of the amount of code files. They are all listed twice ;-)

    9 [Wpf]
    I had some trouble with multiple entry points for my application. MSBuild generated a app.g.cs file implementing a second main method.
    Here is how to disable code generation for the main method (see approach 3): http://www.infosysblogs.com/microsoft/2008/09/how_to_write_custom_main_metho.html
    In short: Go to project properties in Visual Studio and modify the startup application in the Application tab. Set the startup object to Casino.UI.Wpf.Program.

    Good luck ;-)

    Wosi

    ReplyDelete