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 and Code Interactions
There are two fundamental mechanisms through which XAML and code interact:
- An object defined in XAML can fire an event that is handled in the code-behind file.
- 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:
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