1. Problem
You have a large project with many custom controls, templates, styles, etc. that exists in ResourceDictionary objects. You would like to be able to store these ResourceDictionary
objects in separate XAML files or assemblies to keep source code more
manageable, while also allowing updating assemblies to be updated
separately from the main application code.
2. Solution
Use a merged resource dictionary to reference external XAML files and assemblies to better organize code.
3. How It Works
WPF has supported
merged resource dictionaries as a way to improve organization for large
applications. Merged resource dictionaries make it possible to share
resources across applications and are also more conveniently isolated
for localization than with Silverlight 2 where merged resource
dictionaries where not available.
Resources in a merged dictionary
occupy a location in the resource lookup scope just after the scope of
the main resource dictionary they are merged into. Although a resource
key must be unique within any individual dictionary, a key can exist
multiple times in a set of merged dictionaries, because they are
separate namescopes.
Silverlight 3 added support
for merged resource dictionaries, making it more like WPF. Silverlight 3
or later leverages the packed URI format for referencing resources
available in WPF except that you do not have to specify the pack:// protocol reference.
4. The Code
Expression Blend makes it easy
to create a resource dictionary for your application that is merged with
resources within the application itself. In Expression Blend, clicking
the Create New Resource Dictionary button indicated by the arrow in Figure 1 opens the New Item dialog also shown in the figure.
When you click OK, Expression Blend creates a new file in your project with the name specified. It also modifies the app.xaml file by adding the following ResourceDictionary.MergedDictionaries XAMLelement to the Application.ResourceDictionary element:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
To place a style resource into a merged resource dictionary, select the element in Expression Blend and then click the Object => Edit Style =>
Create Empty menu item. To place a control template resource into a
merged resource dictionary, follow the same steps but instead of
clicking Edit Style, select Edit Template. Figure 2
shows what it looks like when you select the Rectangle and want to edit
its Style. Notice that the Resource Dictionary has been selected as the
location where you want to define your new style.
Clicking OK brings up the style editor in Expression Blend. Next, edit the style, and save it.
When you view the Rectangle in the designer, it now has the style applied to it that you just created.Listing 1 has the source code for the Rectangle where the style is applied.
Listing 1. Recipe 1 MainPage.xaml File
<UserControl x:Class="Ch02_ProgrammingModel.Recipe2_13.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/
markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.047*"/>
<ColumnDefinition Width="0.953*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.052*"/>
<RowDefinition Height="0.948*"/>
</Grid.RowDefinitions>
<StackPanel Margin="8" Grid.Column="1" Grid.Row="1">
<Rectangle Stroke="Black" Height="100"
Style="{StaticResource RectangleStyle1}">
</Rectangle>
<TextBlock Text="I'm a TextBlock" TextWrapping="Wrap" Margin="4"/>
<TextBlock Text="I'm another TextBlock" TextWrapping="Wrap" Margin="4"/>
<Button Content="Button" Margin="4"/>
</StackPanel>
</Grid>
</UserControl>
|
You can see that the style RectangleStyle1 is applied to the Rectangle. This recipe shows how the merged resource dictionary is referenced in the App.xaml file. Listing 2 has the source code for the merged resource dictionary.
Listing 2. Recipe 1 ResourceDictionary1.xaml File
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="RectangleStyle1"
TargetType="Rectangle">
<Setter Property="Margin" Value="4"/>
<Setter Property="Fill">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF243300"/>
<GradientStop Color="#FFDEF3AB" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<!-- Resource dictionary entries should be defined here. -->
</ResourceDictionary>
|
In Listing 2, you can see the style named RectangleStyle1
is defined. You can also define merged resource dictionaries in other
assemblies as well. Please refer to the Silverlight 4 documentation for
more information.