Resource Dictionary is a foundational building block to all Xamarin.Forms mobile development. It’s the primary vehicle for declaring XAML resources you’ll use throughout your mobile application, including everything from styles to value converters, content templates, and data templates. In the most recent stable release of Xamarin.Forms, we gained the ability to merge multiple resource dictionaries for even greater flexibility in composing resources. In this article, I’ll show you how to take advantage of that and give you a glimpse at some of the new syntax improvements coming your way.
Merged Dictionaries
Out with the Old
Prior to 2.5.0, you probably found yourself implementing a single resource dictionary per ContentPage
or other control. Every control has a Resources
property of type ResourceDictionary
where you declare reusable resources.
<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>
You might define colors and styles that you wish to use throughout your application at the Application
level in this code.
If you’re really industrious, you might have discovered that you merge one dictionary with another using the MergedWith
property.
<Application ... xmlns:local="using:MyApplication"> <Application.Resources> <ResourceDictionary MergedWith="local:Colors"> <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>
In this example the primary dictionary is being merged with another resource dictionary of colors.
<?xml version="1.0" encoding="utf-8" ?> <ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyApplication.Colors"> <Color x:Key="PageBackgroundColor">Yellow</Color> <Color x:Key="HeadingTextColor">Black</Color> <Color x:Key="NormalTextColor">Blue</Color> </ResourceDictionary>
Using a ResourceDictionary
in this fashion requires a code file to declare the class.
... public partial class Colors : ResourceDictionary { ... }
In with the New
This syntax gets much cleaner with the new implementation of merged dictionaries, and you can merge multiple dictionaries instead of just the one. Instead of using MergedWith
, you now add to a new MergedDictionaries
collection property.
<Application ... xmlns:local="using:MyApplication"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <local:Colors /> <!-- Add more resource dictionaries here --> </ResourceDictionary.MergedDictionaries> <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>
A big thanks to Microsoft MVP Adam Pedley for his proposal and initial pull request for merged dictionaries and for working with us to make this happen.
Upcoming ResourceDictionary Improvements
The next major version of Xamarin.Forms will introduce several improvements to ResourceDictionary
in XAML, which you can get a taste for now in the nightly build feed.
Pure XAML ResourceDictionaries
You’ll notice the Colors.xaml
needs to have a partial class to accompany it in the example above, even though it’s totally empty. That’s no longer required in the nightly build, where you can declare a XAML file without any Class and it will still be compiled with XAML.
Here’s another file Colors.xaml
example, which contains all the colors to be used in an application. The <?xaml-comp compile=”true” ?> does the magic.
<?xml version="1.0" encoding="utf-8" ?> <?xaml-comp compile="true" ?> <ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Color x:Key="AccentColor">#FF4B14</Color> <Color x:Key="BlackOpacityColor">#99253748</Color> <Color x:Key="BlackTextColor">#253748</Color> <Color x:Key="BackgroundColor">#F8F8F8</Color> <Color x:Key="PinkColor">#ED0241</Color> <Color x:Key="GrayColor">#ACB1B4</Color> <Color x:Key="DarkColor">#203446</Color> <Color x:Key="WhiteColor">#FFFFFF</Color> <Color x:Key="GreenColor">#368F95</Color> </ResourceDictionary>
More Concise Syntax XAML can get pretty verbose as you declare all the resources for your application, so we’ve done some work to cut the corners and save some keystrokes. Instead of writing:
<ContentPage.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Colors.xaml" /> </ResourceDictionary.MergedDictionaries> <StyleSheet Source="style.css" /> <Color x:Key="notgreen">FF00FF</Color> </ResourceDictionary> </ContentPage.Resources>
You can simply write:
<ContentPage.Resources> <ResourceDictionary Source="Colors.xaml" /> <StyleSheet Source="style.css" /> <Color x:Key="notgreen">FF00FF</Color> </ContentPage.Resources>
In this new syntax:
- Source: You can now load your dictionary with the new
Source
property. The file should be relative to the document or absolute from the application root - No need to specify a top level
<ResourceDictionary>
, as it’s now created on demand - No need to specify
<ResourceDictionary.MergedDictionaries>
if yourStyleSheet
orResourceDictionary
is keyless
These improvements provide more flexibility for you to organize your application resources and compose them on a control however you need them.
Be Resourceful
Multiple merged dictionaries are available today on NuGet in the Xamarin.Forms 2.5.0 stable release. Be sure to also check out the nightly feed and explore the new features we have on the horizon.
Do you have an idea or request like Adam’s that you’d like to contribute? Start by exploring the enhancements project board on GitHub, and then open an enhancement proposal.
0 comments