series

Xamarin Forms, the MVVMLight Toolkit and I (new series) [Updated]

Updated some code parts that needed to be changed in the ViewModelLocator.

Please see also this post for upgrading the project to .netStandard:

Xamarin Forms, the MVVMLight Toolkit and I: migrating the Forms project and MVVMLight to .NET Standard



Like some of you may have already registered, I have been doing the next step and went cross platform with my personal projects. I am primarily using Xamarin Forms, because I eventually like XAML a little too much. I took a break from round about 2 years on my Xamarin usage, and I am happy to see that it has improved a lot in the meantime. While Xamarin Forms still has room for improvementes, one can do already real and serious projects with it. As I like the lightweight MVVMLight toolkit as much as I like XAML, it was a no-brainer for me to start also my recent Xamarin projects with it.

There is quite some setup stuff to do if you want get everything working from the Xamarin Forms PCL, and this post will be the first in a series to explain the way I am currently using. Some of the things I do may be against good practice for Xamarin Forms, but sometimes one has to break out of them to write code more efficiently and also maintain it easier.

Installing MVVM Light into a Xamarin Forms PCL project

Of course, we will start with a new Xamarin Forms project. After selecting the type Cross Platform App in the New Project Dialog in Visual Studio, you’ll be presented with this screen, which was introduced in the Cycle 9 Release of Xamarin:

Select Xamarin Forms as UI Technology and PCL as Code Sharing Strategy to start the solution creation. As it creates several projects, this may take some time, so you may be able to refill your coffee cup in the meantime. Once the project is created, you’ll see 4 projects:

Before we are going to write some code, we will update and add the additional packages from within the NuGet Package Manager. If your are not targeting the Android versions 7.x , Xamarin Forms is not able to use the latest Android Support libraries, so you’ll have to stick with version 23.3.0 of them (see release notes of Xamarin Forms). Since it makes sense for a new app to target the newest Android version, we’ll be updating the Android Support packages for our sample app as well.

If the NuGet Package manager demands you to restart, you’ll better follow its advise. To verify everything is ok with the updated NuGet packages, set the Android project as Startup project and let Visual Studio compile it.

If all goes well, let’s make sure we are using the right UWP compiler version for Visual Studio 2015. The .NETCORE package for the UWP needs to be of Version 5.2.x, as 5.3 is only compatible with Visual Studio 2017.

Once the packages are up to date, we’ll finally download and install MVVMLight. As we will host all of our ViewModel Logic in Xamarin Forms, together with their Views, we just need to install it into the Portable library and into the UWP project:

There will be no changes to the project except adding the reference. We need to set up the structure ourselves. First, create two new folders, View and ViewModel:

Move the MainPage into the View Folder and adjust the Namespace accordingly. The next step is to setup a ViewModelLocator class, which takes a central part of our MVVM structure. Here is what you need for the base structure:

    public class ViewModelLocator
    {
        private static ViewModelLocator _instance;
        public static ViewModelLocator Instance => _instance ?? (_instance = new ViewModelLocator());

        public void Initialize()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            RegisterServices();        

        }

        private static void RegisterServices()
        {
            //topic of another blog post
        }

        #region ViewModels  
        #endregion

        #region PageKeys
        #endregion
    }

You may notice some things. First, I am using the singleton pattern for the ViewModelLocator to make sure I have just one instance. I had some problems with multiple instances on Android, and using a singleton class helped to fix them. The second part of the fix is to move everything that is normally in the constructor into the Initialize() method. Now let’s go ahead, add a MainViewModel to the project and to the ViewModelLocator:

        public void Initialize()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            RegisterServices();
            if (!SimpleIoc.Default.IsRegistered)
                SimpleIoc.Default.Register<MainViewModel>();
        }

        #region ViewModels
        public MainViewModel MainVm => ServiceLocator.Current.GetInstance<MainViewModel>();
        #endregion

Let’s give the MainViewModel just one property which is not subject to change (at least for now):

public string HelloWorldString { get; private set; } = "Hello from Xamarin Forms with MVVM Light";

The next step is to get the App.xaml file code right, it should look like this:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             x:Class="XfMvvmLight.App" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             d1p1:Ignorable="d" 
             xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:forms="http://xamarin.com/schemas/2014/forms" 
             xmlns:vm="clr-namespace:XfMvvmLight.ViewModel" >
  <Application.Resources>
    <!-- Application resource dictionary -->
    <forms:ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
      <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </forms:ResourceDictionary>
  </Application.Resources>
</Application>

Now that we have set up the baisc MVVM structure, we are going to connect our MainViewModel to our MainPage. There are two ways to do so.

In Xaml:

<ContentPage.BindingContext>
    <Binding Path="MainVm" Source="{StaticResource Locator}" />
</ContentPage.BindingContext>

in Code:

        public MainPage()
        {
            InitializeComponent();

            this.BindingContext = ViewModelLocator.Instance.MainVm;
        }

After that, just use the HelloWorldString property of the MainViewModel as Text in the already existing Label:

    <Label Text="{Binding HelloWorldString}"
           VerticalOptions="Center"
           HorizontalOptions="Center" />

Before we are able to test our code, we need to make sure our ViewModelLocator is initialized properly:

Android:

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            //TabLayoutResource = Resource.Layout.Tabbar;
            //ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            ViewModelLocator.Instance.Initialize();

            LoadApplication(new App());
        }
    }

iOS:

    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();

            ViewModelLocator.Instance.Initialize();

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }
    }

UWP:

//in App.xaml.cs:
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {

#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

            Frame rootFrame = Window.Current.Content as Frame;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();

                rootFrame.NavigationFailed += OnNavigationFailed;

                Xamarin.Forms.Forms.Init(e);

                ViewModelLocator.Instance.Initialize();

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }

                // Place the frame in the current Window
                Window.Current.Content = rootFrame;
            }

            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }
            // Ensure the current window is active
            Window.Current.Activate();
        }

Let’s test our app on all platforms by building and deploying them:

Android

iOS Screenshot – post will be updated 

UWP

If you get the same screens, you are all set up to use Xamarin Forms with MVVMLight.

Conclusion

I know there are several specialized MVVM frameworks/toolkits floating around, which are commonly used for Xamarin Forms. As I am quite used to the MVVMLight toolkit, I prefer it over them. It is a lightweight solution, and I have more control over the code that is running than with the other options. I know I have to handle a lot of things in this case on my own (Navigation for example), but these will get their own blog posts. Starting with one of the future posts in this series, I will provide a sample app on my Github account.

If you have feedback or questions, feel free to get in contact with me via comments or on my social accounts. Otherwise, I hope this post and the following ones are helpful for some of you.

Happy coding, everyone!

Posted by msicc in Android, Dev Stories, iOS, Xamarin, 12 comments

New Series: developing for Android with Xamarin

xamandroid

Prolog

In the last few month I was developing not only my personal projects, but also on my daily 9to5 job. I am working on an internal app that will help to improve the customer experience amongst the customers of my employer Telefónica.

The project has a simple setup in phase I, with collecting data and sending them via mail. The challenge for me was how to get the Windows Phone app (yes, Windows Phone was first!) to Android.

I knew it would take some time to get started with Android development, and was searching for possible solutions to speed things up. I knew from Xamarin already, and was able to obtain a 1-year license for Android (maybe iOS will follow later).

Some of my fellow WinPhans and WinPhanDevs will scream out very loud at the moment. I understand that. But honestly, I could not let go away this huge opportunity for me – as it touches both my daily job and my private developer story. To calm you down: I will always love Windows Phone and Windows and develop for it first. I will always remain a WinPhanDev. But I need to go forward, and this is a big step.

Let’s go back to the topic.

With this blog post, I am kicking off a new blogging series for Android development with Xamarin. The huge advantage of using Xamarin is that I am able to use my C# knowledge to develop apps for other platforms – which makes it a little easier to get things done.

However, if you start with another platform, you still have to learn the platform structure. Without knowing or be willing to learn it, you will be lost very fast. Every OS has its own specific UI rules, save handling and so on. This is what I will blog about.

The Windows Phone app I ported to Android has a item Pivot, which I ported over to Android. It has a little different appearance, but it works in a similar way with tapping the header or a swiping gesture to move between the items/pages.

To get there, I had to learn a lot about Android – and I will share it all with you out there.

My series will cover the following topics:

Installing Xamarin

Installing Xamarin is pretty easy – but will take some time. Click on this link to download the Xamarin IDE. The IDE will ask you for which platform you want to develop for (let’s choose only Android for the moment) and then download a huge amount of additional SDKs like the Java and the Android SDK (Android apps are Java based, if you didn’t knew).

Screenshot (267)

On the screenshot above you can see the starting page of Xamarin Studio. On the left side you have the list of recent solutions, in the middle you see Xamarin news and finally the pre-built apps section.

Xamarin Studio has a lot together with Visual Studio, and you also can take a lot of settings to adjust the appearance for your needs. Let’s start a new project by clicking on the ‘New’ button

Screenshot (270)

Xamarin will set up a .sln file with everything we need for the moment. After creating the project has been created, you’ll see these lines of code:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace gettingstarted
{
	[Activity (Label = "gettingstarted", MainLauncher = true)]
	public class MainActivity : Activity
	{
		int count = 1;

		protected override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);

			// Set our view from the "main" layout resource
			SetContentView (Resource.Layout.Main);

			// Get our button from the layout resource,
			// and attach an event to it
			Button button = FindViewById<Button> (Resource.Id.myButton);

			button.Click += delegate {
				button.Text = string.Format ("{0} clicks!", count++);
			};
		}
	}
}

 

These few lines should help to get started with the basic structure of an Android App.

Android has Activities. Activities can be seen as the code behind files in a C# project. Here begins all the action of an Android app. Xamarin automatically ads the Label (project name) and in this case, also the MainLauncher property, which will run this code on app start up.

To get something displayed in our app, we need to load a Layout or create the view from the code. This is what the SetContentView() method is about. Without this, the app will compile but displays nothing. In this demo app, a basic layout with a button inside is created:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/myButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
</LinearLayout>

 

We already have the first difference to other C# projects here. In order to make the button visible for our code in the Activity, we need to search our resources for the button. This is done by the FindViewById<T>() method. As soon as it is visible to our code, we are able to create a delegate for our button Click event.

The button counts then the clicks on it and changes the text based on the number of clicks.

To understand more about the structure of an Android App, I highly recommend to read the documentation. For me, especially these links were helpful:

There are some more resources that are helpful, but for getting started those four links should be enough. I will cover some of the topics above also with my upcoming posts and link additional resources as well.

As with the Windows Phone development, also StackOverflow is a big help as well as the Xamarin  Android forums.

Until the next post, happy coding!

Posted by msicc in Android, Dev Stories, Xamarin, 0 comments