Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Getting Started with Xamarin.Forms with Resources and Styles

Previous posts in this sequence on Getting Started with Xamarin.Forms:
Multi-Targeting in Visual Studio, SDK Versions, MvvmCross, Authenticating with ADAL
Refactoring MvvmCross and Services, Effects, Navigation with MvvmCross
Presentation Attributes in MvvmCross

In this post we’re going to look at how you can adjust the default style for the controls that you use within your Xamarin.Forms application. To get started, let’s look at how you might change the colour of a basic Label – there are a couple of options but all start with setting the TextColor property:

<Label TextColor="#0F0" />
<Label TextColor="#00FF00" />
<Label TextColor="Green" />

A lot of applications will have all sorts of layout properties set explicitly in the page XAML. Unfortunately this becomes increasingly hard to manage as the application grows. Imagine having 10+ pages all with the colour of elements set explicitly and then you want to change the theme of the application – this would require going through every element to make sure every colour is correct.

An alternative is to extract various properties into static resources where they can be managed at an application, page or even control level. Let’s look at defining an application resource in the App.xaml file in the UI project.

<Application xmlns="http://xamarin.com/schemas/2014/forms"
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              x:Class="StrataPark.UI.App">
     <Application.Resources>
         <Color x:Key="FeatureColor">Green</Color>
    </Application.Resources>
</Application>

In this case we’ve defined a Color resource with a Key of FeatureColor. This can be used anywhere in the application using the Key.

<Label TextColor="{StaticResource FeatureColor}" />

Extract properties into resources can be done for all sorts of values such as strings, colours, margins etc. Not all resources need to be defined at an application level. Resources can be added to the Resources dictionary of a Page or even a control (for example a Grid) – this limits the scope of that resource to the element where the resource is defined, and it’s children. For example, adding a resource to the Resources dictionary of a Page means that the resource is available to all elements on that page but not to elements on other pages within the application.

Note: It may seem simpler to add all resources to the Application Resources dictionary – just be aware that there is a performance cost associated with this as all resources will need to be loaded when the application is started up. Depending on the number and complexity of the resources, this can have a negative impact on the startup time for your application.

Returning to the example of setting the colour of the text of a Label, creating the FeatureColor resource makes it easy to apply the same colour to a number of Label elements and then to be able to change their colour in one place. However, there are two issues here:

- What if we want to be able to set other common properties across all these Label elements? For example, we might want to set FontSize.

- We still have to explicitly set the TextColor on each Label – it would be great if the colour could be set automatically on all Label elements.

The answer to both of these is to define a Style, which you can think of as a collection of property setters, applied by setting the Style property of an element. Let’s start with the first issue where we want to be able to set the FontSize as well as the colour. To do this we’ll create a Style called FeatureLabelStyle, again in the App.xaml so it can be used throughout the application.

<x:Double x:Key="DefaultLabelFontSize">24</x:Double>
<Color x:Key="FeatureColor">Green</Color>

<Style x:Key="FeatureLabelStyle" TargetType="Label">
     <Setter Property="TextColor" Value="{StaticResource FeatureColor}"/>
     <Setter Property="FontSize" Value="{StaticResource DefaultLabelFontSize}"/>
</Style>

Note that we still have a resource called FeatureColor which specifies the colour of the Label, and we have another resource that defines the size to be used for the FontSize. These are combined into the FeatureLabelStyle, which can then be applied by setting the Style property.

<Label Style="{StaticResource FeatureLabelStyle}" />

Moving now to the second issue, which is how we can apply a Style to all Label elements. Currently the Style we have defined has a Key assigned to it, making it an explicit Style, since the Key has to be used in order to explicitly specify the Style. In order to apply it to all elements we need to define an implicit style, a Style with no Key.

<Style TargetType="Label" BasedOn="{StaticResource FeatureLabelStyle}"/>

The implicit Style will be automatically applied by default to all Label elements. Note that we have based the implicit Style on the previously defined explicit style – this is best practice as it means we can take advantage of Style inheritance. For example you might have a base explicit Style that defined the default colour for all Label styles.

And there you have it, a quick overview of using Resources and Styles within your Xamarin.Forms application.

Comments are closed