XAML Markup Extension¶
The XAML markup extension adds additional functionality thats not defined in the standard XAML spec.
x:Static¶
The x:Static
extension can be used to access any one of the following from XAML:
- a public static field
- a public static property
- a public constant field
- an enumeration member
Referencing static fields¶
We can reference any static fields, whether from the .net framework or our own code. In the sample below we will reference a static field from our own class :
MonthsPage.cs
namespace LayoutSample { public partial class MonthsPage : ContentPage { public static string[] Months = new[]{ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; public MonthsPage() { InitializeComponent(); } } }
MonthsPage.xaml.cs
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:LayoutSample" x:Class="LayoutSample.MonthsPage"> <ContentPage.Content> <ListView ItemsSource="{x:Static local:MonthsPage.Months}" /> </ContentPage.Content> </ContentPage>
Note
To refer to the static member, Months
we first have to define the namespace in which the member is found. We define the namespace as follows xmlns:local="clr-namespace:LayoutSample"
.
We can now use the x:Static
extension to refer to the static property Months
defined in the MonthsPage
.
Add a blank space to a label
We are going to use the Environment.NewLine
defined in the System
class to add a newline to the contents of the label.
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" x:Class="DataBindingDemo.SharedResources.MarkupExtensionPage"> <ContentPage.Content> <Label> <Label.FormattedText> <FormattedString> <Span Text="I am the first line" /> <Span Text="{x:Static sys:Environment.NewLine}" /> <Span Text="{x:Static sys:Environment.NewLine}" /> <Span Text="am separated by a new line" /> </FormattedString> </Label.FormattedText> </Label> </ContentPage.Content> </ContentPage>
We define the namespace for System
using the xmlns:sys="clr-namespace:System;assembly=mscorlib"
. Since the property NewLine
is static, we can use it in the Span
with x:Static
extension by using <Span Text="{x:Static sys:Environment.NewLine}" />
.
StaticResource Markup Extension¶
The StaticResource
is XAML markup extension is used to retrieve objects defined in the ResourceDictionary
.
We can use the ResourceDictionary
to keep arbitrary objects referenced by a key. In the following example, we define a color resource and double resource. We use the keys when defining the resources. We can then later on use the StaticResource
to retrieve the object by the key.
<ContentPage.Resources> <ResourceDictionary> <Color x:Key="ColorPrimary">#ff9900</Color> <x:Double x:Key="BorderSize">1</x:Double> </ResourceDictionary> </ContentPage.Resources>
Use the color resource defined as follows :
<Button Text="Login" BorderColor="{StaticResource ColorPrimary}" BorderWidth="{StaticResource BorderSize}" />
Platform Specific Keys¶
We can define keys that should be only be available on a specific platform using the OnPlatform
. Since the OnPlatform
is a generic object, we will need to specify the x:TypeArguments
.
<ResourceDictionary> <OnPlatform x:Key="PaddingiOS" x:TypeArguments="Thickness" iOS="0,20,0,0" /> </ResourceDictionary>
The object will only be available on iOS, and we can use it the same way.
<StackLayout Padding="{x:StaticResource PaddingiOS}"> </StackLayout>
Accessing the Resources in Code¶
We can access the objects defined in the ResourceDictionary
by accessing them using the Resources
property. Since its a dictionary, we can use the key to retrieve the object.
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DataBindingDemo.App"> <Application.Resources> <ResourceDictionary> <Color x:Key="ColorPrimary">#CC0033</Color> </ResourceDictionary> </Application.Resources> </Application>
We have defined a color in the application resources. The resources defined in the application resources will be available anywhere in the app. We can use both XAML or code to access them.
Let's retrieve the color and apply it to navigation bar :
MainPage = new NavigationPage(new MainTabsPage()) { BarBackgroundColor = (Color)Resources["ColorPrimary"], BarTextColor = Color.White };
Since we know the resource object is type color, we were bold as cast it to the Color
class.
DynamicResource
XAML Markup Extension¶
The DynamicResource
extension is similar to the StaticResource
extension with one difference, it maintains a reference to the object. If the resource changes, then the updates are reflected.
If we have the following in the resource dictionary :
<ResourceDictionary> <x:String x:Key="CurrentDate">Will show a date if accessed dynamically</x:String> </ResourceDictionary>
and then use the StatiResource
and DynamicResource
to access the same key, you will notice that the one accessed using the DynamicResource
will update since we have a timer running every second :
<Label Text="{StaticResource CurrentDate}" /> <Label Text="{DynamicResource CurrentDate}" />
and in code we update the resource :
Device.StartTimer(TimeSpan.FromSeconds(1), () => { Resources["CurrentDate"] = DateTime.Now.ToString("hh:mm:ss"); return true; });