Boost your Xamarin native projects with MvvmCross

With Xamarin you are able to develop cross-platform apps. But what if you are using Xamarin native (instead of Xamarin.Forms) and you want to maximize your code re-use even further? When using MvvmCross you are even able to share parts of your presentation layer and UI logic.

Xamarin native and MccmCross a powerfull combination

In my previous blog I’ve described the differences between Xamarin native and Xamarin.Forms. In this blog I’ll explain all the benefits that MvvmCross offers you to boost your cross-platform app project. When we choose to develop with Xamarin.Forms we are quite stuck with the same UI over the multiple platforms. There are of course options to define different renderers per platform with Xamarin.Forms, but you don’t have the same freedom as you’ll have with Xamarin native. If your project requires slightly different UI per platform to maximize the look and feel of that specific platform, you should go with Xamarin native. For a developer that means you need to develop a separate UI layer per platform. But what if we could maximize code re-use by even sharing parts of the presentation layer and UI logic?

MvvmCross
MvvmCross is a cross-platform MVVM framework that supports your development of cross-platform apps. This frameworks allows you to use the Model-View-ViewModel pattern. Which we .NET developer all love to use! This allows us to move the ViewModels to a portable project (PCL) and re-use this code throughout all the different UI projects. The MvvmCross framework offers you a lot more neat features which I’ll describe in the next paragraphs. There are loads of great tutorials available on the world wide web so I will only focus on the power of MvvmCross instead of describing step-by-step how to set-up a cross-platform app with MvvmCross. Installing MvvmCross on your project can be easily done via a NuGet package:

PM > Install-Package MvvmCross

Setting up MVVM
When MvvmCross is installed on your portable project (PCL) and all available app projects, we can start setting up the MVVM pattern. There is not much to do, as it’s pretty much available out of the box. Just create a ViewModel class that inherits from the MvxViewModel of MvvmCross. Create some properties and call the RaisePropertyChanged() method in the setter (just like you need to do for other MVVM frameworks). Now you’ve set-up a ViewModel that’s ready for databinding.

Now your ViewModel is ready we can create views (pages) for each app project. For Windows Phone it is just like a regular Windows Phone project as the MVVM pattern is a common pattern to use with Windows Phone development. But for Android and iOS this is not possible out-of-the-box. That’s where MvvmCross comes in. The MvvmCross framework allows you to also use databinding on your Android and iOS ‘views’! When setting up databinding you are also able to use two way binding (reading input from user), work with commands (click events and such) and use converters (format your data to display).

Databinding Android
For Android you only have to setup the required ViewModel class on your Activity and then you are able to do databinding on your AXML layout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="Text Title" />
</RelativeLayout>

Databinding iOS
For iOS it works almost the same, only you are unable to do databinding on your storyboard / XIB layout. You need to set-up the databinding from your code behind of your view class. Other than that the databinding works the same.

Navigation
To navigate between screens you need to trigger the navigation from your presentation layer. MvvmCross therefore has created ViewModel to ViewModel navigation. This means that within your ViewModel (which is located in your portable project) you can navigate to another ViewModel. As you’ve registered each ViewModel to a View, MvvmCross knows which view/screen to show. This way you can secure your application workflow in your portable project, instead of having to configure/develop your application workflow for each platform separately. In your MvxApplication class you can register the first ViewModel to show on your app start up.

Some more examples on how to navigate between ViewModels:

Inversion of Control
The key elements of the MvvmCross framework are the Service Location design pattern and the Inversion of Control design principle. With the static Mvx class you are able to register and resolve interfaces and their implementations.

public interface IDialogService
{
void Alert(string message, string title, string okBtnText);
}

public class DialogService : IDialogService
{
public void Alert(string message, string title, string okBtnText)
{
//code to show an alert
}
}

//register interface and its implementation as a singleton
Mvx.RegisterSingleton<IDialogService>(new DialogService());

//resolve the implementation of IFoo
var foo = Mvx.Resolve<IDialogService>();

foo.Alert("message", "title", "OK");

All registered interfaces are now available for Constructor Injection on your ViewModels e.g.

public class YourViewModel : MvxViewModel
{
public string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
RaisePropertyChanged(() => Title);
}
}

public YourViewModel(IFoo foo)
{
this.Title = foo.DoSomething()
}
}

Platform specific functionality

The real power of the Inversion of Control comes in play when platform specific functionality is required. For example a dialog. To display a dialog on Android, iOS or Windows Phone it all needs platform specific code. What if you could create an interface on your portable project (PCL) and do the implementation in each app specific project?

Create an Android specific implementation inside your Android project:

public class AndroidDialogService : IDialogService
{
public void Alert(string message, string title, string okBtnText)
{
var top = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
var act = top.Activity;

var adb = new AlertDialog.Builder(act);
adb.SetTitle(title);
adb.SetMessage(message);
adb.SetIcon(Resource.Drawable.Icon);
adb.SetPositiveButton(okBtnText, (sender, args) => { /* some logic */ });
adb.Create().Show();
}
}

And register this Android specific implementation on your MvxAndroidSetup class:

Now you are able to resolve and use the interface in your portable project (PCL) and for each platform the implementation is being handled according to the specific platform. Wow!

Plugins
There are also a bunch useful plugins available for MvvmCross. All these plugins can be installed via the NuGet Package Manager. Most of these plugins provide platform specific functionality being implemented on each platform specific project to use in your portable project so you don’t have to develop them yourselves. You are also able to develop your own MvvmCross plugin and re-use this across your different apps or even share this with other developers.

Wrapping up
MvvmCross allows you to share parts of the presentation layer and some of the UI logic in your portable project (PCL). This improves your code re-use and will speed up your cross-platform app development. With Dependency Injection and Plugins you are also able to write platform specific functionality, but still call these functionalities from your portable project (PCL). Together with the MVVM pattern and the power of databinding, MvvmCross will boost your Xamarin native apps!