Xamarin.Forms Deep Dive

PDF for offline use

Let us know how you feel about this

Translation Quality


0/250

last updated: 2016-12

In the Xamarin.Forms Quickstart, the Phoneword application was built. This article reviews what has been built in order to gain an understanding of the fundamentals of how Xamarin.Forms applications work.

The following topics are examined:

  • Introduction to Xamarin Studio – Introduction to Xamarin Studio, and creating a new Xamarin.Forms application.
  • Introduction to Visual Studio – Introduction to Visual Studio, and creating a new Xamarin.Forms application.
  • Anatomy of a Xamarin.Forms Application – Tour of the essential parts of a Xamarin.Forms application.
  • Architecture and Application Fundamentals – How the application is launched on each platform.
  • User Interface (UI) – Creating user interfaces in Xamarin.Forms.
  • Additional Concepts Introduced in Phoneword – Brief descriptions of additional concepts used in the Phoneword application.
  • Testing and Deployment – Completing the application with advice on testing, deployment, generating artwork, and more.

Introduction to Xamarin Studio

Xamarin Studio is a free, open-source IDE similar to Visual Studio. It features a fully integrated visual designer, a text editor complete with refactoring tools, an assembly browser, source code integration, and more. For more information about Xamarin Studio, see Introducing Xamarin Studio.

Xamarin Studio follows the Visual Studio practice of organizing code into Solutions and Projects. A Solution is a container that can hold one or more Projects. A Project can be an application, a supporting library, a test application, and more. The Phoneword application consists of one solution containing three projects, as shown in the following screenshot.

The projects are:

  • Phoneword – This project is the portable class library (PCL) project that holds all of the shared code and shared UI.
  • Phoneword.Droid – This project holds Android specific code and is the entry point for Android applications.
  • Phoneword.iOS – This project holds iOS specific code and is the entry point for iOS applications.

Introduction to Visual Studio

Visual Studio is a powerful IDE from Microsoft. It features a fully integrated visual designer, a text editor complete with refactoring tools, an assembly browser, source code integration, and more. This article focuses on using some of the basic Visual Studio features with the Xamarin plug-in.

Visual Studio organizes code into Solutions and Projects. A Solution is a container that can hold one or more Projects. A Project can be an application, a supporting library, a test application, and more. The Phoneword application consists of one solution containing six projects, as shown in the following screenshot.

The projects are:

  • Phoneword – This project is the portable class library (PCL) project that holds all of the shared code and shared UI.
  • Phoneword.Droid – This project holds Android specific code and is the entry point for the Android application.
  • Phoneword.iOS – This project holds iOS specific code and is the entry point for the iOS application.
  • Phoneword.UWP – This project holds Universal Windows Platform (UWP) specific code and is the entry point for the UWP application.
  • Phoneword.WinPhone – This project holds the Windows Phone specific code and is the entry point for the Windows Phone 8.0 application.
  • Phoneword.WinPhone81 – This project holds the Windows Phone 8.1 specific code and is the entry point for the Windows Phone 8.1 application.

Anatomy of a Xamarin.Forms Application

The following screenshot shows the contents of the Phoneword PCL project in Xamarin Studio:

The following screenshot shows the contents of the Phoneword PCL project in Visual Studio:

The project consists of three folders:

  • References – Contains the assemblies required to build and run the application. Expanding the .NET Portable Subset folder reveals references to .NET assemblies such as System, System.Core, and System.Xml. Expanding the From Packages folder reveals references to the Xamarin.Forms assemblies.
  • Packages – The Packages directory houses NuGet packages that simplify the process of using third party libraries in your application. These packages can be updated to the latest releases by right-clicking the folder and selecting the update option in the pop-up menu.
  • Properties – Contains AssemblyInfo.cs, a .NET assembly metadata file. It is good practice to fill this file with some basic information about your application. For more information about this file, see AssemblyInfo Class on MSDN.

The project consists of two folders:

  • References – Contains the assemblies required to build and run the application.
  • Properties – Contains AssemblyInfo.cs, a .NET assembly metadata file. It is good practice to fill this file with some basic information about your application. For more information about this file, see AssemblyInfo Class on MSDN.

The project also consists of a number of files:

  • App.xaml – The XAML markup for the App class, which defines a resource dictionary for the application.
  • App.xaml.cs – The code-behind for the App class, which is responsible for instantiating the first page that will be displayed by the application on each platform, and for handling application lifecycle events.
  • IDialer.cs< – The IDialer interface, which specifies that the Dial method must be provided by any implementing classes.
  • MainPage.xaml – The XAML markup for the MainPage class, which defines the UI for the page shown when the application launches.
  • MainPage.xaml.cs – The code-behind for the MainPage class, which contains the business logic that is executed when the user interacts with the page.
  • packages.config – An XML file that contains information about the NuGet packages being used by the project, in order to track required packages and their respective versions. Both Xamarin Studio and Visual Studio can be configured to automatically restore any missing NuGet packages when sharing the source code with other users. The content of this file is controlled by the NuGet package manager and should not be manually edited.
  • PhoneTranslator.cs – The business logic that is responsible for converting a phone word to a phone number, which is invoked from MainPage.xaml.cs.

For more information about the anatomy of a Xamarin.iOS application, see Anatomy of a Xamarin.iOS Application. For more information about the anatomy of a Xamarin.Android application, see Anatomy of a Xamarin.Android Application.

Architecture and Application Fundamentals

A Xamarin.Forms application is architected in the same way as a traditional cross-platform application. Shared code is typically placed in a Portable Class Library (PCL), and platform-specific applications consume the shared code. The following diagram shows an overview of this relationship for the Phoneword application:

For more information about PCLs, see Introduction to Portable Class Libraries.

To maximize the reuse of startup code, Xamarin.Forms applications have a single class named App that is responsible for instantiating the first page that will be displayed by the application on each platform, as shown in the following code example:

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace Phoneword
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new MainPage();
        }
        ...
    }
}

This code sets the MainPage property of the App class to a new instance of the MainPage class. In addition, the XamlCompilation attribute turns on the XAML compiler, so that XAML is compiled directly into intermediate language. For more information, see XAML Compilation.

Launching the Application on Each Platform

iOS

To launch the initial Xamarin.Forms page in iOS, the Phoneword.iOS project includes the AppDelegate class that inherits from the FormsApplicationDelegate class, as shown in the following code example:

namespace Phoneword.iOS
{
    [Register ("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init ();
            LoadApplication (new App ());
            return base.FinishedLaunching (app, options);
        }
    }
}

The FinishedLaunching override initializes the Xamarin.Forms framework by calling the Init method. This causes the iOS-specific implementation of Xamarin.Forms to be loaded in the application before the root view controller is set by the call to the LoadApplication method.

Android

To launch the initial Xamarin.Forms page in Android, the Phoneword.Droid project includes code that creates an Activity with the MainLauncher attribute, with the activity inheriting from the FormsApplicationActivity class, as shown in the following code example:

namespace Phoneword.Droid
{
    [Activity (Label = "Phoneword.Droid",
               Icon = "@drawable/icon",
               MainLauncher = true,
               ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            global::Xamarin.Forms.Forms.Init (this, bundle);
            LoadApplication (new App ());
        }
    }
}

The OnCreate override initializes the Xamarin.Forms framework by calling the Init method. This causes the Android-specific implementation of Xamarin.Forms to be loaded in the application before the Xamarin.Forms application is loaded.

Universal Windows Platform

In Universal Windows Platform (UWP) applications, the Init method that initializes the Xamarin.Forms framework is invoked from the App class:

Xamarin.Forms.Forms.Init (e);

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
  ...
}

This causes the UWP-specific implementation of Xamarin.Forms to be loaded in the application. The initial Xamarin.Forms page is launched by the MainPage class, as demonstrated in the following code example:

namespace Phoneword.UWP
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.LoadApplication(new Phoneword.App());
        }
    }
}

The Xamarin.Forms application is loaded with the LoadApplication method.

User Interface

There are four main control groups used to create the user interface of a Xamarin.Forms application.

  1. Pages – Xamarin.Forms pages represent cross-platform mobile application screens. The Phoneword application uses the ContentPage class to display a single screen. For more information about pages, see Xamarin.Forms Pages.
  2. Layouts – Xamarin.Forms layouts are containers used to compose views into logical structures. The Phoneword application uses the StackLayout class to arrange controls in a horizontal stack. For more information about layouts, see Xamarin.Forms Layouts.
  3. Views – Xamarin.Forms views are the controls displayed on the user interface, such as labels, buttons, and text entry boxes. The Phoneword application uses the Label, Entry, and Button controls. For more information about views, see Xamarin.Forms Views.
  4. Cells – Xamarin.Forms cells are specialized elements used for items in a list, and describe how each item in a list should be drawn. The Phoneword application does not make use of any cells. For more information about cells, see Xamarin.Forms Cells.

At runtime, each control will be mapped to its native equivalent, which is what will be rendered.

When the Phoneword application is run on any platform, it displays a single screen that corresponds to a Page in Xamarin.Forms. A Page represents a ViewGroup in Android, a View Controller in iOS, or a Page on the Universal Windows Platform. The Phoneword application also instantiates a ContentPage object that represents the MainPage class, whose XAML markup is shown in the following code example:

<?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="Phoneword.MainPage">
             ...
    <ContentPage.Content>
        <StackLayout VerticalOptions="FillAndExpand"
                     HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     Spacing="15">
            <Label Text="Enter a Phoneword:" />
            <Entry x:Name="phoneNumberText" Text="1-855-XAMARIN" />
            <Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />
            <Button x:Name="callButton" Text="Call" IsEnabled="false" Clicked="OnCall" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

The MainPage class uses a StackLayout control to automatically arrange controls on the screen regardless of the screen size. Each child element is positioned one after the other, vertically in the order in which they are added. The amount of screen space used by the StackLayout is dependent upon the values of the HorizontalOptions and VerticalOptions properties. In this case, the FillAndExpand value indicates that the StackLayout has no padding around itself, and expands. The StackLayout control contains a Label control to display text on the page, an Entry control to accept textual user input, and two Button controls used to execute code in response to touch events.

For more information about XAML in Xamarin.Forms, see Xamarin.Forms XAML Basics.

Responding to User Interaction

An object defined in XAML can fire an event that is handled in the code-behind file. The following code example shows the OnTranslate method in the code-behind for the MainPage class, which is executed in response to the Clicked event firing on the Translate button.

void OnTranslate(object sender, EventArgs e)
{
    translatedNumber = Core.PhonewordTranslator.ToNumber (phoneNumberText.Text);
    if (!string.IsNullOrWhiteSpace (translatedNumber)) {
        callButton.IsEnabled = true;
        callButton.Text = "Call " + translatedNumber;
    } else {
        callButton.IsEnabled = false;
        callButton.Text = "Call";
    }
}

The OnTranslate method translates the phoneword into its corresponding phone number, and in response, sets properties on the call button. The code-behind file for a XAML class can access an object defined in XAML using the name assigned to it with the x:Name attribute. The value assigned to this attribute has the same rules as C# variables, in that it must begin with a letter or underscore and contain no embedded spaces.

The wiring of the translate button to the OnTranslate method occurs in the XAML markup for the MainPage class:

<Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />

Additional Concepts Introduced in Phoneword

The Phoneword application for Xamarin.Forms has introduced several concepts not covered in this article. These concepts include:

  • Enabling and disabling buttons. A Button can be toggled on or off by changing its IsEnabled property. For example, the following code example disables the callButton:

    callButton.IsEnabled = false;
  • Displaying an alert dialog. When the user presses the call Button the Phoneword application shows an Alert Dialog with the option to place or cancel a call. The DisplayAlert method is used to create the dialog, as shown in the following code example:

    await this.DisplayAlert (
            "Dial a Number",
            "Would you like to call " + translatedNumber + "?",
            "Yes",
            "No");
  • Accessing native features via the DependencyService class. The Phoneword application uses the DependencyService class to resolve the IDialer interface to platform-specific phone dialing implementations, as shown in the following code example from the Phoneword project:

    async void OnCall (object sender, EventArgs e)
    {
        ...
        var dialer = DependencyService.Get<IDialer> ();
        ...
    }

    For more information about the DependencyService class, see Accessing Native Features via the DependencyService.

  • Placing a phone call with a URL. The Phoneword application uses OpenURL to launch the system phone app. The URL consists of a tel: prefix followed by the phone number to be called, as shown in the following code example from the iOS project:

    return UIApplication.SharedApplication.OpenUrl (new NSUrl ("tel:" + number));
  • Tweaking the platform layout. The Device class enables developers to customize the application layout and functionality on a per-platform basis, as shown in the following code example that uses a different Padding value on the iOS platform to correctly display each page:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 ...>
         <ContentPage.Padding>
            <OnPlatform x:TypeArguments="Thickness"
                        iOS="20, 40, 20, 20"
                        ... />
         </ContentPage.Padding>
       ...
    </ContentPage>

    For more information about platform tweaks, see Device Class.

Testing and Deployment

Xamarin Studio and Visual Studio both provide many options for testing and deploying an application. Debugging applications is a common part of the application development lifecycle and helps to diagnose code issues. For more information, see Set a Breakpoint, Step Through Code, and Output Information to the Log Window.

Simulators are a good place to start deploying and testing an application, and feature useful functionality for testing applications. However, users will not consume the final application in a simulator, so applications should be tested on real devices early and often. For more information about iOS device provisioning, see Device Provisioning. For more information about Android device provisioning, see Set Up Device for Development.

Summary

This article has examined the fundamentals of application development using Xamarin.Forms. Topics covered included the anatomy of a Xamarin.Forms application, architecture and application fundamentals, and the user interface.

In the next section of this guide the application will be extended to include multiple screens in order to explore more advanced Xamarin.Forms architecture and concepts.

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.