Introduction to XAML

Avatar

David

XAML (eXtensible Application Markup Language) allows you to define user interfaces in Xamarin.Forms applications using markup rather than code. Using XAML, you can define user interfaces using all of the Xamarin.Forms views, layouts, and pages, as well as custom classes.

XAML has several advantages over equivalent code:

  • XAML is often more succinct and readable than equivalent code.
  • XAML allows a clean separation of the appearance of an application from its code, therefore enabling a clean designer-developer workflow.
  • XAML mimics the parent-child hierarchy of user interface objects with greater visual clarity.

There is no performance hit for creating a user interface in XAML, rather than C#, because XAML can be compiled directly into intermediate language (IL) using the XAML compiler (XAMLC).

In this blog post, I’m going to explore using XAML to create a Xamarin.Forms page and demonstrate how to interact with code from XAML.

Getting Started

In a Xamarin.Forms application, XAML is mostly used to define the visual contents of a page. A XAML file is always associated with a C# code file that provides code support for the markup. The following code example shows a basic XAML class:

<?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="HelloWorld.HomePage">

</ContentPage>

The two XML namespace declarations (xmlns) refer to non-existent URIs that function as version identifiers. The first XML namespace declaration specifies that elements defined within the XAML file with no prefix refer to Xamarin.Forms classes, such as ContentPage. The second namespace declaration specifies that elements defined within the XAML with a prefix of x, are used for elements and attributes that are intrinsic to XAML (specifically the 2009 XAML specification).

The x prefix is used for an attribute named Class, whose value is HelloWorld.HomePage (a fully qualified .NET class name). This specifies that the XAML file defines a new class named HomePage, that derives from ContentPage (the element in which the x:Class attribute appears), in the HelloWorld namespace. The x:Class attribute can only appear in the root element of a XAML file to define a derived C# class.

The associated code-behind file is shown in the following code example:

using Xamarin.Forms;

namespace HelloWorld
{
    public partial class HomePage : ContentPage
    {
        public HomePage ()
        {
            InitializeComponent ();
        }
    }
}

The HomePage class derives from the ContentPage class, and is a partial class definition. During the build process, a C# code file is generated from the XAML file. This is the other partial class definition of HomePage, and it contains the definition of the InitializeComponent method called from the HomePage constructor. During the build process, the two partial class definitions of HomePage are compiled together.

Given the HomePage class, which is a page, how will it be displayed by a Xamarin.Forms application? Each Xamarin.Forms application contains an App class, derived from the Application class. The following code example shows the App class from the sample application:

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

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

The MainPage property on the Application class is used to set the root page of the application. Therefore, when the sample application runs, a new instance of the HomePage class will be created and displayed.

In addition, in the App class, the HelloWorld namespace is decorated with the XamlCompilation attribute. By prefixing the attribute with assembly, it’s used to perform compile-time checking of all of the XAML contained within the HelloWorld namespace. This offers a number of benefits:

  • You are notified of any XAML errors.
  • It removes some of the load and instantiation time for XAML elements.
  • It helps to reduce the file size of the final assembly.

Setting Page Content

A ContentPage contains a Content property which is typically set to a layout with child views. In XAML, a layout can be implicitly set to the Content property of the page by being placed between the start and end ContentPage tags, as demonstrated in the following code example:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloWorld.HomePage">
    <StackLayout Padding="0,20,0,0">
        <Slider Minimum="0" Maximum="100" VerticalOptions="CenterAndExpand" />
        <Label Text="0" HorizontalTextAlignment="Center" VerticalOptions="CenterAndExpand" FontSize="Large" FontAttributes="Bold" TextColor="Red" />
        <Button Text="Click Me" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Within the XAML file, classes (e.g. ContentPage, StackLayout, Label etc.) and properties (e.g. FontSize, Text, TextColor etc.) are referenced with XML elements and attributes and links between the markup and code can be established.

In XAML, parent-child relationships are established with a normal XML hierarchy. Therefore, the child of the ContentPage is a StackLayout. The StackLayout class contains a Children property, which can be populated with multiple views or other layouts. In XAML, the children can be implicitly set to the Children property of the layout by being placed between the start and end layout tags. The StackLayout contains three children: Slider, Label, and Button, which have various properties set on them that specify their appearance. This results in the page shown in the following screenshots:

xaml-1

XAML and Code Interactions

There are two fundamental mechanisms through which XAML and code interact:

  1. An object defined in XAML can fire an event that is handled in the code-behind file.
  2. The code-behind file can access an object defined in XAML using the name assigned to it with the x:Name attribute.

The following code example from the sample application demonstrates these mechanisms:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloWorld.HomePage">
    <StackLayout Padding="0,20,0,0">
        <Slider ... ValueChanged="OnValueChanged" />
        <Label x:Name="valueLabel" ... />
        <Button ... Clicked="OnButtonClicked" />
    </StackLayout>
</ContentPage>

When the Slider value changes, the ValueChanged event fires and is handled in the code-behind file by the OnValueChanged method. The Label has a name assigned to it with the x:Name attribute, which allows it to be accessed from the code-behind file. When the Button is clicked, the Clicked event fires and is handled in the code-behind file by the OnButtonClicked event. The following code example shows the code-behind file:

public partial class HomePage : ContentPage
{
	public HomePage ()
	{
		InitializeComponent ();
	}

	void OnValueChanged (object sender, ValueChangedEventArgs args)
	{
		valueLabel.Text = args.NewValue.ToString ("F3");
	}

	async void OnButtonClicked (object sender, EventArgs args)
	{
		await DisplayAlert ("Clicked", "The button was clicked", "OK");
	}
}

The Text property of the Label is set to the new Slider value in response to the Slider.ValueChanged event firing when the OnValueChanged method is executed. In response to the Button.Clicked event firing when the OnButtonClicked method is executed, an alert is displayed using the DisplayAlert method. The OnButtonClicked method is defined as async because the DisplayAlert method is asynchronous and should be prefaced with the await operator, which returns when the method completes. The following screenshots show the alert displayed by the OnButtonClicked method:

xaml-2

Wrapping Up

XAML allows you to define user interfaces in Xamarin.Forms applications using markup rather than code. Using XAML, you can define user interfaces using all of the Xamarin.Forms views, layouts, and pages, as well as custom classes. There is no performance hit for creating a user interface using XAML rather than C# because XAML can be compiled directly into intermediate language (IL) using the XAML compiler (XAMLC).

XAML and code can interact by XAML objects firing an event that’s handled in the code-behind file and by using the name assigned to a XAML object with the x:Name attribute from code-behind.

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

0 comments

Comments are closed.