This article is compatible with the latest version of Silverlight.
Merged Resource Dictionaries provide a way to define and split resources into separate files. By locating application resources in external file we can then reuse them between applications. This feature can be helpful in custom control development, but not only.
In Silverlight 2 resources cannot be factored into separate files and that leads to large App.xaml file holding application-wide shared resources. The same problem exists while developing custom controls. All default style keys must be specified in Themes/Generic.xaml which again leads to very large file.
Merged Resources Dictionaries are a great solution for these problems – you are free to split style definitions and other resources into manageable pieces, making it easy to localize and revise.
Download Source Code
Usage
Ok, enough theory. Let’s see how to make use of MergedDictionaries.
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..." />
<ResourceDictionary Source="..." />
<ResourceDictionary Source="..." />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
MergedDictionaries contain a collection of ResourceDictionary objects with specified Source attribute. The Source points to the file where the ResourceDictionary is defined.
ResourceDictionary is defined in external XAML file (in the same or different assembly) with root element ResourceDictionary like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<SolidColorBrush x:Key="TitleBrush" Color="DarkViolet" />
<SolidColorBrush x:Key="ContentBrush" Color="Black" />
</ResourceDictionary>
There are several ways to use a merged resource dictionary which are indicated by the URI format that you will use. You can either include your resource .xaml file in the project as Resource or as Content.
If you include it as a Resource you don’t need to copy the resource file to the output directory. You can use it by specifying the URI in the following format:
Source=”/<assembly name>;component/<resource file name>”
You can also use a Content build action. Then the URI format is the following:
Source=”<resource file name>”
To use a resource defined in external assembly you just need a reference to the DLL and then you just have to set the Source path including the external assembly name.
All the 3 cases of using merged resource dictionaries we discuss, are included in the attached sample project and are illustrated by the following example:
<UserControl x:Class="MergedResourceDictionaries.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="BrushResources.xaml" />
<ResourceDictionary Source="/ExternalResources;component/DataResources.xaml" />
<ResourceDictionary Source="/MergedResourceDictionaries;component/TextResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="TitleStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="18" />
<Setter Property="Foreground" Value="{StaticResource TitleBrush}" />
</Style>
<Style x:Key="ContentStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ContentBrush}" />
</Style>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<TextBlock Style="{StaticResource TitleStyle}" Text="Merged Resource Dictionaries" />
<TextBlock Style="{StaticResource ContentStyle}" Text="A great way to manage and reuse resources" />
<TextBlock Text="{StaticResource MRD}" />
<ListBox>
<TextBlock Text="{StaticResource Silverlight3}"/>
<TextBlock Text="{StaticResource WPF}"/>
</ListBox>
</StackPanel>
</UserControl>
On line 7 we use a resource included as a Content in the project which contains two SolidColorBrushes – TitleBrush and ContentBrush used on line 13 and 16.
On line 8 we use a resource included as a Resource in the same project.
On line 9 we use a resource included as a Resource in external assembly referenced by our project.
Performance
Christian Moser from WPFTutorial.net talks about merged resource dictionaries performance in one of his tutorials - Improve the performance of merged ResourceDictionaries. There he states:
“Each time a control references a ResourceDictionary
XAML creates a new instance of it. So if you have a custom control library with 30 controls in it and each control references a common dictionary you create 30 identical resource dictionaries!”
That’s absolutely true. He created a SharedResourceDictionary that helps you get rid of this problem. Read his tutorial to learn more about that.
Read more
Merged Resource Dictionaries on MSDN
Improve the performance of merged ResourceDictionaries