Merged Dictionaries In Xamarin.Forms

Placing styles and other resources in your ResourceDictionary is a great way to reuse these elements through your page or application. However, up until now, you could only merge with one external resource dictionary, using MergedWith. With MergedDictionaries, you can now separate out your styles into multiple files, and merge them as desired on each page.

Note: I personally wrote this feature in Xamarin.Forms. My PR 1138 has been merged, with many thanks to Stephane for the code review. This is now available in Xamarin.Forms 2.5.0 and above.

How To Use

Create a new XAML file, and create your resource dictionary, as below.  I called the my new file, MyResourceDictionary.

<?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="Mobile.Style.MyResourceDictionary"> 
    <Style TargetType="Button"> 
        <Setter Property="TextColor" Value="White" /> 
    </Style>
</ResourceDictionary>

Then, in your ContentPage, do the following.

<?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:theme="clr-namespace:Mobile.Style"
             x:Class="Mobile.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary.MergedDictionaries>
            <theme:MyResourceDictionary />
            <!-- Add as many as you want here -->
        </ResourceDictionary.MergedDictionaries>
    </ContentPage.Resources>
</ContentPage>

Or, you can even do this, if you want to get creative, but I recommend the first approach.

<ContentPage.Resources>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary MergedWith="theme:MyResourceDictionary">
            <Style TargetType="Button"> 
                <Setter Property="TextColor" Value="White" /> 
            </Style>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ContentPage.Resources>

Searching

A ResourceDictionary, could have the same key as a dictionary that is merged via MergedWith or MergedDictionaries. When the page is trying to find a key, it uses this search method.

  1. Check in page’s local keys
  2. Check MergedWith ResourceDictionary
  3. Check each MergedDictionaries, in the order they are listed

The first place it finds the key, it uses that key. Hence the priority is set based on the list above.

Performance Considerations

Searching resource dictionaries, involves checking every key, until it finds something suitable. If you have a large amount of keys, and the key you are looking for is right at the end, and you use this key multiple times, it may impact performance. It is best to ensure you only place the appropriate resource dictionaries in your page, to avoid unnecessary searching.

Why MergedWith and not Source

UWP and WPF use Source as their property name, not MergedWith. Currently, the resource dictionary has the MergedWith tag to merge one Resource Dictionary, with another. It is planned that the Source attribute will be used in the future, but will also support finding dictionaries based on URI as well. Once this occurs, it is expected that MergedWith, will be deprecated.


Posted

in

by

Tags: