Refactoring XAML ResourceDictionaries

Code reuse of any kind is a priority for all developers. Design elements and UI resources are no exception.
In this tutorial you will learn how to correctly organize your resources for maximum reuse.

Considering the following scenario:
You have two apps: App1 and App2 int which you want to use the same resource but with slightly different properties.
App1 needs a style for a TextBlock

<Style x:Name="myTextBlockStyle" TargetType="TextBlock" >
    <Setter Property="Foreground" Value="Green"/>
    <Setter Property="FontSize" Value="24"/>

while App2 needs a very similar style

<Style x:Name="myTextBlockStyle" TargetType="TextBlock" >
    <Setter Property="Foreground" Value="Orange"/>
    <Setter Property="FontSize" Value="24"/>

Notice that the only different thing about the two styles is the color used as Foreground, the rest is similar. For the sake of simplicity I kept the myTextBlockStyle quite small, with only two properties.

For maximizing our code reuse we can try to refactor the two styles into a separate style as follows:

<Style x:Name="commonTextBlockStyle" TargetType="TextBlock" >
    <Setter Property="Foreground" Value="Green/Orange"/>
    <Setter Property="FontSize" Value="24"/>

Now, the magical part!

If you use a common ClassLibrary you can move the style into a dictionary which both apps reference.

The style definition becomes:

<Style x:Name="commonTextBlockStyle" TargetType="TextBlock" >
    <Setter Property="Foreground" Value="{StaticResource brush1}"/>
    <Setter Property="FontSize" Value="24"/>

Notice how the Foreground value is not longer set to either Green or Orange, but it references another resource named brush1.

In order for the whole setup to work this resource has to be defined in the ClassLibrary as follows:

<SolidColorBrush x:Key="brush1" Color="Red" />

And overriden in App1:

<SolidColorBrush x:Key="brush1" Color="Green" />

and in App2:

<SolidColorBrush x:Key="brush1" Color="Orange" />

At runtime, each app will have to reference the dictionary file where commonTextBlockStyle using an absolute path

The dictionary file that defines commonTextBlockStyle will in turn have to reference another dictionary path that contains the definition of brush1 using a relative path.

The following diagrams illustrate the setup in greater detail:

Project structure

ClassLibrary1 structure

StandardStyles in the ClassLibrary referenes a Common style referenced in the same project

App1 at runtime

App1 references StandardStyles and overrides Common with the desired color Green

App2 at runtime

App2 references StandardStyles and overrides Common with the desired color Orange.

This project structure and reference mechanism should greatly reduce your dictionary size while giving you all the flexibility you need for using your styles in whatever way you need.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s