Resource Dictionaries

Re-using XAML resources

PDF for offline use:
Sample Code:
Related Articles:
Related APIs:

Let us know how you feel about this.


0/250
Thanks for the feedback!

last updated: 2016-06

XAML resources are definitions of objects that can be used more than once. A ResourceDictionary allows resources to be defined in a single location, and re-used throughout a Xamarin.Forms application. This article demonstrates how to create and consume a ResourceDictionary, and how to merge one ResourceDictionary into another.

Overview

A ResourceDictionary is a repository for resources that are used by a Xamarin.Forms application. Typical resources that are stored in a ResourceDictionary include styles, control templates, data templates, colors, and converters.

In XAML, resources are defined in a ResourceDictionary and then retrieved and applied to elements by using the StaticResource markup extension. In C#, resources are defined in a ResourceDictionary and then retrieved and applied to elements by using a string-based indexer. However, there's little advantage to using a ResourceDictionary in C#, as resources can easily be directly assigned to properties of visual elements without having to first retrieve them from a ResourceDictionary.

Creating and Consuming a ResourceDictionary

Resources can be defined in a ResourceDictionary that's attached to the Resources collection of a page or control, or to the Resources collection of the application. Choosing where to define a ResourceDictionary impacts where it can be used:

  • Resources in a ResourceDictionary defined at the control level can only be applied to the control and to its children.
  • Resources in a ResourceDictionary defined at the page level can only be applied to the page and to its children.
  • Resources in a ResourceDictionary defined at the application level can be applied throughout the application.

The following XAML code example shows resources defined in an application level ResourceDictionary:

<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="PageBackgroundColor">Yellow</Color>
            <Color x:Key="HeadingTextColor">Black</Color>
            <Color x:Key="NormalTextColor">Blue</Color>
            <Style x:Key="LabelPageHeadingStyle" TargetType="Label">
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

This ResourceDictionary defines three Color resources and a Style resource. For more information about creating a XAML App class, see App Class.

Each resource have a key that is specified using the x:Key attribute, which gives it a descriptive key in the ResourceDictionary. The key is used to retrieve a resource from the ResourceDictionary by the StaticResource markup extension, as demonstrated in the following XAML code example that shows additional resources defined in a control level ResourceDictionary:

<StackLayout Margin="0,20,0,0">
  <StackLayout.Resources>
    <ResourceDictionary>
      <Style x:Key="LabelNormalStyle" TargetType="Label">
        <Setter Property="TextColor" Value="{StaticResource NormalTextColor}" />
      </Style>
      <Style x:Key="MediumBoldText" TargetType="Button">
        <Setter Property="FontSize" Value="Medium" />
        <Setter Property="FontAttributes" Value="Bold" />
      </Style>
    </ResourceDictionary>
  </StackLayout.Resources>
  <Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
    <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
           Margin="10,20,10,0"
           Style="{StaticResource LabelNormalStyle}" />
    <Button Text="Navigate"
            Clicked="OnNavigateButtonClicked"
            TextColor="{StaticResource NormalTextColor}"
            Margin="0,20,0,0"
            HorizontalOptions="Center"
            Style="{StaticResource MediumBoldText}" />
</StackLayout>

The first Label instance retrieves and consumes the LabelPageHeadingStyle resource defined in the application level ResourceDictionary, with the second Label instance retrieving and consuming the LabelNormalStyle resource defined in the control level ResourceDictionary. Similarly, the Button instance retrieves and consumes the NormalTextColor resource defined in the application level ResourceDictionary, and the MediumBoldText resource defined in the control level ResourceDictionary. This results in the appearance shown in the following screenshots:

Note that resources that are specific to a single page shouldn't be included in an application level resource dictionary, as such resources will then be parsed at application startup instead of when required by a page. For more information, see Reduce the Application Resource Dictionary Size.

Overriding Resources

When ResourceDictionary resources share x:Key attribute values, resources defined lower in the view hierarchy will take precedence over those defined higher up. For example, setting the PageBackgroundColor resource to Blue at the application level will be overridden by a page level PageBackgroundColor resource set to Yellow. Similarly, a page level PageBackgroundColor resource will be overridden by a control level PageBackgroundColor resource. This precedence is demonstrated by the following XAML code example:

<ContentPage ... BackgroundColor="{StaticResource PageBackgroundColor}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="PageBackgroundColor">Blue</Color>
            <Color x:Key="NormalTextColor">Yellow</Color>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Margin="0,20,0,0">
        ...
        <Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
        <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
               Margin="10,20,10,0"
               Style="{StaticResource LabelNormalStyle}" />
        <Button Text="Navigate"
                Clicked="OnNavigateButtonClicked"
                TextColor="{StaticResource NormalTextColor}"
                Margin="0,20,0,0"
                HorizontalOptions="Center"
                Style="{StaticResource MediumBoldText}" />
    </StackLayout>
</ContentPage>

The original PageBackgroundColor and NormalTextColor instances, defined at the application level, are overridden by the PageBackgroundColor and NormalTextColor instances defined at page level. Therefore, the page background color becomes blue, and the text on the page becomes yellow, as demonstrated in the following screenshots:

However, note that the background bar of the NavigationPage is still yellow, because the BarBackgroundColor property is set to the value of the PageBackgroundColor resource defined in the application level ResourceDictionary.

Merged Resource Dictionaries

A merged resource dictionary combines one ResourceDictionary into another. This is accomplished by setting the ResourceDictionary.MergedWith property to the ResourceDictionary to be merged into the application, page, or control level ResourceDictionary. The following XAML code example demonstrates this:

<Application ... xmlns:theme="clr-namespace:Xamarin.Forms.Themes;assembly=Xamarin.Forms.Theme.Light">
    <Application.Resources>
        <ResourceDictionary MergedWith="theme:LightThemeResources">
            <Color x:Key="PageBackgroundColor">Yellow</Color>
            <Color x:Key="HeadingTextColor">Black</Color>
            <Color x:Key="NormalTextColor">Blue</Color>
            ...
        </ResourceDictionary>
    </Application.Resources>
</Application>

The ResourceDictionary specified as the value of the MergedWith property is merged into the current ResourceDictionary instance. Note that any resources in the current ResourceDictionary that share x:Key attribute values with resources in the ResourceDictionary to be merged, will be replaced.

Summary

This article demonstrated how to create and consume a ResourceDictionary, and how to merge one ResourceDictionary into another. A ResourceDictionary allows resources to be defined in a single location, and re-used throughout a Xamarin.Forms application.

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.