Using #Xamarin Forms with #mvvmlight

.NET, MVVM, Phone, Technical stuff, Windows Phone, Work, Xamarin, XAML
29 Comments

Update: Sample source code

Update 2: The always awesome Daniel Plaisted made me aware that you can, in fact, add one Nuget package to multiple projects at the same time. Updated the article to reflect this fact.

Update 3: Fixed my faulty assertions about the StaticResource.

A few weeks ago, Xamarin released a new framework on top of their Xamarin solution. This framework called Xamarin Forms allows easy sharing of not only business code (like the “traditional” Xamarin offering) but also UI.


How does it work?

Xamarin created a collection of pages and controls. The package currently includes 5 different page types, 7 layouts and 24 controls. Of course we can expect these numbers to grow any time soon with new elements to build flexible applications.

When you build the application, you select the most appropriate control for your purpose. The existing controls should cover a large range of scenarios.

At run time, the controls are rendered differently for each platform. For example a tabbed page will be rendered differently for on Android, iOS and Windows Phone. On each of these platforms, the most appropriate user experience is used. The screenshots below (taken from the Xamarin Forms documentation) show this in action.

Tabbed page rendered on Windows Phone (pivot)

01wp

Tabbed page rendered on Android

01Android

Tabbed page rendered on iPhone

01ios

 

And XAML and DataBinding

One thing interesting with Xamarin Forms is the introduction of XAML as UI language for all supported platforms. While you can build the whole UI in code behind (just like on Windows platforms), you can also have a XAML front end coupled with a C# code behind. In addition, and maybe most importantly, Xamarin Forms supports DataBinding! This is great because it lowers the learning curve greatly for people coming from the XAML space into iOS and Android. Even though the XAML looks a bit different from the traditional Windows-based XAML, with different namespaces and different controls, it is a promising first step on getting designer support and a closer development experience from the awesomeness that is the development experience in the Microsoft XAML world.

No designer

At the time of writing, there is no designer support for the Xamarin Forms XAML. If you try to open such a page in Blend, it won’t even render a design surface. However Xamarin Forms is very young and I have no doubt that XAML support will make a designer possible. Looking forward to that, and to enabling design time support through MVVM Light!

Not much intellisense

Almost more annoying than the lack of a designer, Intellisense doesn’t work well in the XAML editor on Visual Studio either. It is when you miss the tools we are used to that we finally realize what an amazing job Microsoft did with their XAML development environment. But hey, this is bleeding edge, and I am sure that these small issues will get sorted out eventually.

An MVVM Light example

Thanks to the built-in DataBinding support in Xamarin Forms, using MVVM Light is even more straightforward than is classic Xamarin. Here is a quick sample with two pages and navigation.

First, let’s create a new Xamarin Forms application supporting Android, iOS and Windows Phone. Note that you have two possible choices: Using a Portable Class Library (PCL) for your business logic, or using shared files.

PCL

In the PCL case, you will have three applications (iOS, Android, Windows Phone) and one additional project (PCL) in which you will put the shared code and the shared XAML. This is the case we are going to take for the demo in this article. This kind of architecture builds 4 different assemblies (iOS, Android, Windows Phone, PCL) which will be packed into three different packages (iOS, Android, Windows Phone).

Shared files

In this architecture, you still have three applications (iOS, Android, Windows Phone) and a shared “virtual folder” in which you can place the shared code and XAML. This is the same architecture than in a Windows Universal application. The shared files will automatically be linked into the three projects by Visual Studio when the applications get built. You will end up with three assemblies (iOS, Android, Windows Phone) packed into three packages.

Creating the new application(s)

We will start this demo by creating a new application. As usual with Xamarin, you can use either Visual Studio or Xamarin Studio. Here we will use Visual Studio, which is probably more familiar to the readers of this blog.

  • Start Visual Studio
  • Select File, New project.
  • Under Mobile Apps, select Blank App (Xamarin.Forms Portable)
  • Create the new app.

02-Jul-14 9-59-21 PM

Like we mentioned, you will see 4 projects in the newly created solution.

02-Jul-14 10-07-04 PM

Note that only Windows Phone Silverlight 8 is available at the moment, not Windows Phone 8.1.

Then we will add MVVM Light to all the projects.

Update: You can add the same Nuget package to multiple projects in a Solution with the following steps:

  • Right click on the Solution file and select Manage Nuget Packages for Solution.
  • Select Nuget.org on the left, and type mvvmlight in the search field.
  • Select the package names “MVVM Light Libraries Only (PCL)” and click install.
  • Select which projects the package must be installed into (which, in our case, is all 4 of them).

Creating a new XAML page

Running the applications now will already show some content, but what we would like to see is XAML in action. Let’s add a shared XAML page with the following steps:

  • Right click on the PCL project and select Add, New Item
  • Select Forms Xaml Page.
  • Note that the name still shows Class.cs. This is a bug. Change this to MyPage.xaml and click on Add.

This creates a new XAML page with code behind (MyPage.xaml.cs). Windows developers are already familiar with this file pair. The code behind is a little like a controller for the XAML view, and this is where event handlers will get implemented. Currently, the XAML code looks like this (formatting added by yours truly):

Figure 1: Original XAML markup of MyPage.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamFormsDemo.MyPage">
    <Label Text="{Binding MainText}"
              VerticalOptions="Center"
              HorizontalOptions="Center" />
</ContentPage>

As you can see, this is not “classic XAML”: the default xmlns points to a different namespace, and there are other differences such as the VerticalOptions and HorizontalOptions.

Before we take care of the UI, let’s add a ViewModel. To do this, add a ViewModel folder to the PCL project, and two new classes called MainViewModel and ViewModelLocator. Note that the usage of ViewModelLocator is not strictly necessary here, we add it for consistency with “classic XAML” applications.

Right click on the PCL project and select Add, New Folder. Name this folder ViewModel.

  • In the ViewModel folder, add a new class named MainViewModel.cs
  • Then add another class in the same folder named ViewModelLocator.cs.
  • Implement the classes as shown in figure 2 and figure 3

Figure 2: ViewModelLocator.cs

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<MainViewModel>();
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }
}

Figure 3: MainViewModel.cs

public class MainViewModel : ViewModelBase
{
    /// <summary>
    /// The <see cref="ClickCount" /> property's name.
    /// </summary>
    public const string ClickCountPropertyName = "ClickCount";

    private int _clickCount;

    /// <summary>
    /// Sets and gets the ClickCount property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public int ClickCount
    {
        get
        {
            return _clickCount;
        }
        set
        {
            if (Set(() => ClickCount, ref _clickCount, value))
            {
                RaisePropertyChanged(() => ClickCountFormatted);
            }
        }
    }

    public string ClickCountFormatted
    {
        get
        {
            return string.Format("The button was clicked {0} time(s)", ClickCount);
        }
    }

    private RelayCommand _incrementCommand;

    /// <summary>
    /// Gets the IncrementCommand.
    /// </summary>
    public RelayCommand IncrementCommand
    {
        get
        {
            return _incrementCommand
                ?? (_incrementCommand = new RelayCommand(
                () =>
                {
                    ClickCount++;
                }));
        }
    }
}

Configuring App.cs and the ViewModelLocator

As I mentioned earlier, the ViewModelLocator is not strictly necessary, and I introduced it in this sample to be consistent with the way that we do MVVM in Windows-XAML. I like to have a ViewModelLocator, it’s a convenient place to do some setup and manage the ViewModels’ lifetime.

In Windows-XAML, we create the ViewModelLocator as a global resource in App.xaml. Here we do not have this possibility, so instead we will create it as a static member of the App class, which is also acting as a global class for the Xamarin.Forms app.

Since we are in App.cs already, let’s take this occasion to use the XAML page instead of the ContentPage which was created in code directly. We will instantiate the new MyPage and return it in the GetMainPage method, which is automatically called by the Xamarin.Forms app when it starts up.

Edit the code of App.cs to look like shown in figure 4. Note that in Visual Studio, you might see a “red squiggly line” indicating an error saying that it cannot convert the expression. You can ignore that error, it’s just a bug.

Figure 4: App.cs, MyPage and ViewModelLocator

public class App
{
    private static ViewModelLocator _locator;

    public static ViewModelLocator Locator
    {
        get
        {
            return _locator ?? (_locator = new ViewModelLocator());
        }
    }


    public static Page GetMainPage()
    {
        return new MyPage();
    }
}

DataContext vs BindingContext

Now that we have a ViewModel, we can assign it as the page’s DataContext. In Xamarin.Forms however, the DataContext is named BindingContext. I am not quite sure why they decided not to name it DataContext, but it’s a small learning curve so let’s just get over it.

Edit: You can set the BindingContext in XAML if you want to, and contrarily to what I said first, there are StaticResources in Xamarin XAML. However in this scenario, setting the BindingContext in XAML does not bring a real advantage over setting it in code behind. The XAML route is beneficial when you have a designer like Blend who is able to instantiate the resources at design time, thus enabling design time data. Here, let’s just keep it simple, but it is true that my first assertion was incorrect! Thanks to the commenters who pointed that to me :)

One difference between Windows-XAML and Xamarin-XAML is that the BindingContext cannot be set in XAML (in fact there are no concepts of StaticResource). So instead we will just use the code behind to do that. Edit MyPage.xaml.cs as shown in figure 5. Here too, you might get some red errors in Visual Studio, these can be ignored and are bugs of the Xamarin.Forms integration.

Figure 5: MyPage.xaml.cs

public partial class MyPage
{
    public MyPage()
    {
        InitializeComponent();
        BindingContext = App.Locator.Main;
    }
}

Finally, we can edit the XAML markup to connect to the MainViewModel, which is already set as the application’s DataContext (well, BindingContext). This is shown in figure 6.

Figure 6: New MyPage.xaml markup

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamFormsDemo.MyPage">

    <Button Text="{Binding ClickCountFormatted}"
            Command="{Binding IncrementCommand}"
            VerticalOptions="Center" />

</ContentPage>

Running the application for test

Now is the time to run the application! First let’s try Windows Phone, by setting the XamFormsDemo.WinPhone project as Startup project (right click on the project in the Solution Explorer and select this option from the context menu).

Then press Ctrl-F5 to run it. Depending on your options, this will start the application in the Windows Phone simulator or on a connected device.

Figure 7: Running the app in the Windows Phone emulator

04-Jul-14 6-56-04 PM

For Android, you can choose to use the default emulators, but they are really slow. I prefer to use Genymotion which is probably the best Android emulator around at the moment. Of course you can also use a connected physical device. Here too, select the project and set it as Startup, and then press Ctrl-F5.

Figure 8: Running the app in the Android emulator

04-Jul-14 7-08-37 PM

Finally, we can also run the app in iOS. For this you need a Mac connected through the network. Check the Xamarin documentation for more information on how to do this. If you choose the iPhone simulator, it will run on the Mac. Here too you can connect an iPhone to the Mac in question, and select that device.

Figure 9: Running the app on the iOS simulator

04-Jul-14 7-15-08 PM

Note: Sometimes I have issues running the app directly from Visual Studio into the Mac-based iOS simulator. I assume there are still a few bugs remaining there. If that is the case for you, you can always copy the app on a memory stick, plug it in the Mac and use Xamarin Studio on the Mac to run and debug the application.

And the rest of the application?

This is of course a simple example but the beauty of Xamarin is that you can use standard .NET for your business layer and viewmodel layer. So you can really write this once and run it on the three platforms we just tested. Using an HttpClient to connect to a web service, for example, is a breeze. You can even connect to WCF services, use databases, do complex calculations, use Nuget packages such as JSON.Net, etc etc etc.

Thanks to MVVM Light on all three platforms, you can use all the standard decoupled mechanisms that we know and love on Windows-XAML. The IOC container (SimpleIoc) just works, as do the Messenger, RelayCommands, ObservableObject and ViewModelBase, etc. So not only can we use the skills we know, but we can even leverage existing code (for example from an existing Windows Phone or Windows 8 (or even WPF) applications and easily adapt it for usage in the Xamarin world.

Conclusion

Xamarin is probably the first client-side code-sharing framework that doesn’t smell like cheating. Because the applications that it creates are genuine native apps, you don’t have to compromise like with all the so-called “Hybrid” frameworks that are most of the time using HTML for the UI, running on a Web view encapsulated into a native shell. Honestly, and while it might make sense for some rare apps, this kind of Frankenstein model makes me shiver. Here on the other hand, we have true native apps, with a true native look and feel and true native performance.

The Xamarin.Forms model is interesting because it allows to quickly create a UI (or rather three UIs) to run the app for multiple purposes: Creating simple user experience, for example for a line of business app with limited external exposure; to quickly test complex business logic and demonstrate the use cases to stakeholders; to prototype new functionalities; etc.

Hopefully this simple example was helpful. In the next few months, I will publish more examples of MVVM Light applications on Xamarin, and create more complex examples. Also (and there will be a more formal announcement), if you visit the Evolve conference in October in Atlanta, I will have a session there talking about MVVM Light, Xamarin and Xamarin.Forms. I cannot wait to be there and share my experiences with you all.

Happy coding!
Laurent

GalaSoft Laurent Bugnion
Laurent Bugnion (GalaSoft)

Share on Facebook
 

29 Responses to “Using #Xamarin Forms with #mvvmlight”

  1. Using Xamarin Forms with MVVMLight Says:

    […] /* 0) { ratingctl00_cphMiddle_cphContent_tr3w45fwwvre_itemRating = result['Rating']; SetCurrentRating('ctl00_cphMiddle_cphContent_tr3w45fwwvre_itemRating_pnlHolder', result['Rating'], "disabled fullStar", "disabled emptyStar", true); if(votesCountctl00_cphMiddle_cphContent_tr3w45fwwvre_itemRating!=null) { votesCountctl00_cphMiddle_cphContent_tr3w45fwwvre_itemRating ++; SetVotesCount('ctl00_cphMiddle_cphContent_tr3w45fwwvre_itemRating_lblUsersRated', '(' + votesCountctl00_cphMiddle_cphContent_tr3w45fwwvre_itemRating + ' votes)'); } SetRatingCookie('r', 'i35769', '1'); } else if (result['Status'] == 1) { alert('The session has expired. Please refresh the page to be able to vote!'); } } /* ]]> */ (0 votes) 0 comments   /   posted by Silverlight Show on Jul 09, 2014 Tags:   xamarin , mvvm-light , windows-phone , wpdev , laurent-bugnion Read original post at Laurent Bugnion's Blog […]

  2. gattaca Says:

    I find a good sample on Github (https://github.com/xamarin/xamarin-forms-samples/tree/master/EmployeeDirectory)

    The sample only has three views(Login=>List=>Edit).

    Could you do it by mvvmlight?

    I thought Xamarin.Forms.MessagingCenter look like mvvmlight…

  3. gattaca Says:

    Could you give us another example?
    Just show three views(Login=>List=>Edit)

  4. lbugnion Says:

    I hear you. I’ll try to provide a similar sample.

  5. Ward Bell Says:

    Thanks for this intro.

    Got it going in Android but failed in WinPhone with the error “The ‘ProductID’ attribute is invalid – The value ‘341ae997-b18a-4fcf-9ade-9d1ef946c219′ is invalid according to its datatype ‘http://WPCommontypes:ST_Guid’ – The Pattern constraint failed.” Does this ring a bell?

    Also, when I used the “Blank App (Xamarin.Forms Portable)” template to create the solution, it generated a different kind of project for WinPhone, a “Windows Phone 8.0″ project, rather than the “Windows Phone Silverlight 8″ project that you predicted. Did I miss a step?

  6. Stuart Hallows Says:

    You say “One difference between Windows-XAML and Xamarin-XAML is that the BindingContext cannot be set in XAML (in fact there are no concepts of StaticResource).” Actually that’s not right.
    You could set the BindingContext in Xamarin-XAML like this (once you’d declared the local namespace);

    And Xamarin-XAML fortunately does have StaticResources – see Petzold’s article: http://tinyurl.com/ma8ozuq.

  7. lbugnion Says:

    Hey Ward!

    To your first question, I don’t know what’s happening there. Never saw this error before, sorry :/

    To the second question, I suspect that you have Windows Phone 8 SDK installed but not Windows Phone 8.1. That could explain the discrepancy. They only started to add the “Silverlight” mention to differentiate from Windows Phone 8.1 which is RT based and not Silverlight based.

    Cheers
    Laurent

  8. lbugnion Says:

    Yes you are correct. I got confused by the lack of intellisense and the fact that the way I typically declare my static resources didn’t seem to work. I will amend the article.

    In the case of Xamarin Forms at this point, there are no real advantages in declaring the DataContext in XAML as opposed to code behind. The real advantage of having it in XAML is when opening the XAML document in Blend (or the VS designer). Blend will actually instantiate the static resource and this enables the developer to run design time code. In Xamarin Forms, this wouldn’t work, and so I am OK declaring it in code for now.

    Thanks for the feedback
    Laurent

  9. Shah Says:

    @Ward Bell…

    I think i might have found a solution for your problem. It happend to me too in the past. I have blogged about it here

    http://icomeicicode.blogspot.com/2014/07/the-productid-attribute-is-invalid.html

    Have a go at it. Hope it can solve your problem.

    thanks,
    Shah

  10. lbugnion Says:

    Soubds great, thanks Shah!

  11. My thoughts on Xamarin Forms | Getting Deep into .net Says:

    […] built in classes then you can hook up any MVVM Framework. In fact Laurent Bugnion has a very good post about using MvvmLight […]

  12. mwaring Says:

    Great cutting edge stuff, Look forward to future articles :)

  13. Scott Smith Says:

    Great article! I am new to mvvmlight and trying to get a feel for the proper way to use it in a Xamarin.Forms app. Is there a preferred means of handling navigation from view models, so that the view models remain unaware of the views in the system, and thus more testable?

  14. lbugnion Says:

    Hi,

    Thanks for your message. Yes absolutely, I recommend an abstracted navigation approach. I am preparing a series of articles on this topic, and I will also talk about this at my Xamarin Evolve session in the beginning of October.

    Cheers
    Laurent

  15. Joel Says:

    Thanks, Laurent! This got me up and running in no time. Very much appreciated.

  16. Bruce Says:

    Hi Laurent,

    I’m getting back into this whole MVVM / Mobile thing after too long away on something else. Having used MVVM since Silverlight 4 days when you and Pete Brown were publishing books on the subject.

    I have been trying to follow this article using the latest version of forms ( as of 30.06/2015) and notice that there are now differences and that this does not drop in smoothly as it once did.

    A couple of questions :-) Will you be updating this article for July 2105 ?

    I also have been looking at some more recent samples of MVVM and Xamarin and perhaps you could clear something up for me. Have you used Xamarin forms / MVVM and native UI e.g. android axml files ?

    is this at all possible ? Your latest Tabbed page demo with the monkeys uses a PCL Xaml form and no native UI. but your Flowers sample uses MVVM and native UI ? Are the benefits to use one or the other. I tempted to go native UI to try to avoid issues with Xaml writing without an editor. I notice that This is button text does not seem to work in Xamarin forms ( what else i don’t know worries me too )

    Regards..

    B…

  17. Filip Says:

    I tried this example in Visual Studio 2013 with an Android tablet. NuGet says that the package “MVVM Light libraries only (PCL)” is discontinued, and suggests to use the package with the id “MvvmLightLibs” instead, which is what I did.

    I have found out that the example does not display anything unless I add this constructor to the “App” class:

    public App()
    {
    this.MainPage = App.GetMainPage();
    }

  18. lbugnion Says:

    Hi,

    Yes the PCL was discontinued because now the mvvmlightlibs package is using PCL itself, so it was not necessary to keep both anymore.

    I will check why the sample doesn’t work as is and update if needed. Thanks for the feedback.

    Laurent

  19. Brady Joslin Says:

    Laurent – Xamarin Forms changed how things work in 1.3 and the sample appears to do things the old way.

    See section 2.2 in this link.
    https://developer.xamarin.com/guides/cross-platform/macios/updating-xamarin-forms-apps/

    “We have completely removed the GetMainPage method, and instead set the MainPage property on the Application subclass…The App class is then passed to a new LoadApplication method in each app project”

    So, in app.cs this:

    public static Page GetMainPage()
    {
    return new MyPage();
    }
    }

    should now be this:

    public App ()
    {
    MainPage = new MyPage();
    }

    The existing sample code works if you download it, but if you try and follow it by typing it into a new Xamarin Forms app, you will run into problems regarding this change.

  20. lbugnion Says:

    Thanks for the note. I will update the sample

  21. Dushyant Bangal Says:

    Hi,
    Xamarin.Forms has its own ICommand implementation – Xamarin.Forms.Command, why use RelayCommand? Does it have some significance or the Xamarin.Forms.Command wasn’t there when you wrote this code?

  22. lbugnion Says:

    Hi,

    MVVM Light was released in 2009 and RelayCommand was around before that even, so it’s a fairly old component. It actually comes from a good friend of mine, Josh Smith, who had this clever idea. The rest of us are just copying him really ;)

    The Xam.Forms MVVM stuff is good IMHO as a gateway to MVVM frameworks and if you only have Xam.Forms apps, it probably makes sense to use it. The main advantage of going with another framework (MVVM Light or other) is that you can also use them on other platforms (MVVM Light runs on all Windows XAML platforms including Windows 10 universal, as well as Xamarin.iOS and Xamarin.Android). So if that is ever an ambition of yours, learning a “standard” framework is probably a good idea. Other than that, most of the components that Xam.Forms MVVM is exposing are quite similar to what MVVM Light offers.

    HTH
    Laurent

  23. Russ Says:

    I am looking for a EventToCommand example. I have a list that I want to use EventToCommand to bind the Selected event

  24. lbugnion Says:

    Hi,

    Do you mean with Xamarin Forms? That won’t work, EventToCommand is only available for Windows XAML, not for Xamarin Forms XAML. It might be possible to port it relatively easily, see some documentation at http://codeworks.it/blog/?p=205 or http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/behaviors/

    Take care
    Laurent

  25. Russ Williams Says:

    Correct, I want to use EventToCommand in Xamarin.Forms app development. I wasn’t sure if it was available so it’s nice to have that confirmation.

    I was thinking about coding up a behavior to handle this but wasn’t sure how to do that generically and it seemed a bit brute force to have to code up a behavior for each control type.

    Is genericizing an EventToCommand for Xamarin.Forms using behaviors something that is on the roadmap for MVVM Light or are there still some missing pieces in XF that are needed to port EventToCommand to XF?

  26. DeMark Says:

    Hi,
    Laurent, thank you very much. This got me startet with mvvm in xamarin.
    I wonder though. How do you use MasterDetailPages and CarouselPages with you NavigationService.
    You do not support Modal Pages either?!

  27. Kevin Ledama Says:

    Hi @Laurent, how would you advice one to set up MVVMLight with a MasterDetailPage architecture especially in regards to navigation where we can’t set the navigation in the App.cs file but on the detail page.

  28. Michelangelo Says:

    Greetings, I have a problem with MainViewModel an Locato. In particular when program call this:

    public MainViewModel Main
    {
    get
    {
    return ServiceLocator.Current.GetInstance();
    }
    }

    I have this error (either on Android and iOS):
    system.reflection.targetinvocationexception exception has been thrown by the target of an invocation.

    My code is like git source, only difference is Binding in XAML.
    Please can anyone help me?

  29. lbugnion Says:

    Hi,

    This error usually indicates that something went wrong when the object that you are getting from the ServiceLocator is created. Place a break point in your viewmodel constructor and debug from there.

    Good luck
    Laurent

Leave a Reply