Click here to Skip to main content
15,884,986 members
Articles / Desktop Programming / WPF
Tip/Trick

WPF Resource Dictionary Basics

Rate me:
Please Sign up or sign in to vote.
4.19/5 (5 votes)
14 Sep 2017CPOL3 min read 52.7K   819   6   3
I present a short introduction to resource dictionaries with examples.

Introduction

The resource dictionary is a simple way to simplify the coding of WPF views, but the syntax can be less than obvious. In this short tip, I present a brief description of the following:

  1. Defining constants within a resource dictionary within a view.
  2. Defining styles within a resource dictionary within a view.
  3. Using items in a resource dictionary in a separate file in the same assembly.
  4. Using items located in a resource dictionary in a separate assembly.

It is assumed that you have a basic understanding of WPF, including styles.

Background

The new WPF view designer soon learns that she wants to create controls that have the same look and feel, and that entering the same text time and time again is tedious. The solution of course is to use a resource dictionary, whereby common values such as the width of a button or the style for a group box are stored in a common area, and referenced by multiple controls.

This has the advantage that development is quicker as styles can be reused, the application has a more consistent look and feel as similar controls use the same style, and the application styles are easily modified as they are defined in a common location.

Defining A Constant

The following example defines a constant in a view's resource dictionary:

XML
<Window x:Class="WpfResourceDictionaryDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;assembly=mscorlib"     
        Background="#DCE8F3"
        Title="Resource Dictionary Demo Application"
        Height="350"
        Width="600">
    <Window.Resources>
        <ResourceDictionary>
            <System:Double x:Key="ButtonWidth">80</System:Double>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Margin="10">//

The constant is called 'ButtonWidth', it is a double, and it has the value 80.

Using the constant is quite simple:

XML
<Button Grid.Row="6" Grid.Column="0" Content="Press Me" 
Width="{StaticResource ButtonWidth}" HorizontalAlignment="Left"/>

Thus, the width of the control has been set equal to the value defined by 'ButtonWidth'. Note that the Double type is defined in the System namespace which references the mscorlib component.

Defining A Style

The following example defines a style in a view's resource dictionary:

XML
<Window x:Class="WpfResourceDictionaryDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;assembly=mscorlib"     
        Background="#DCE8F3"
        Title="Resource Dictionary Demo Application"
        Height="350"
        Width="600">
    <Window.Resources>
        <ResourceDictionary>
            <System:Double x:Key="ButtonWidth">80</System:Double>
            <Style x:Key="groupBoxStyle" TargetType="GroupBox">
                <Setter Property="Margin" Value="3"/>
                <Setter Property="Padding" Value="5,5,5,5"/>
                <Setter Property="Background" 
                Value="{StaticResource ResourceKey=backgroundBrush}"/>
                <Setter Property="BorderBrush" Value="Black"/>
            </Style>
        </ResourceDictionary>
    </Window.Resources>

The style called 'groupBoxStyle' can be applied to a group box as follows:

XML
<GroupBox Header="Styles Example One" Style="{StaticResource groupBoxStyle}">
    <Label>Styles defined in the window XAML</Label>
</GroupBox>

The style is easily modified as follows:

XML
<GroupBox Grid.Row="8" Grid.Column="0" 
Name="_borderBottom" Header="Override a resource dictionary style">
    <GroupBox.Style>
        <Style TargetType="GroupBox" BasedOn="{StaticResource groupBoxStyle}">
            <Style.Triggers>
                <DataTrigger Binding="
                {Binding ElementName=_checkBoxYellowBackground, Path=IsChecked}" 
                Value="true">
                    <Setter Property="Background"  Value="LightYellow" />
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=_checkBoxYellowBackground, 
                Path=IsChecked}" Value="false">
                    <Setter Property="Background"  Value="LightCoral" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </GroupBox.Style>
    <CheckBox Grid.Row="8" Grid.Column="0" 
    x:Name="_checkBoxYellowBackground" Content="Yellow Background"/>
</GroupBox>

Thus, the group box style element overrides the 'canned' style and sets the background colour according to the check state of a check box.

Creating A Resource Dictionary File

Clearly a view's resource dictionary is very useful, but what if we want multiple views to have the same resources? The answer is to add a resource dictionary to the project. This is no more than a file with one element called ResourceDictionary. Here is a simple example:

XML
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Brush x:Key="backgroundBrush">#DCE8F3</Brush>
    <Style x:Key="groupBoxStyleRedBorder" TargetType="GroupBox">
        <Setter Property="Margin" Value="3"/>
        <Setter Property="Padding" Value="5,5,5,5"/>
        <Setter Property="Background" Value="PaleVioletRed"/>
        <Setter Property="BorderBrush" Value="Blue"/>
        <Setter Property="BorderThickness" Value="1"/>
    </Style>
    <Style x:Key="borderRedNoLine" TargetType="Border">
        <Setter Property="Background" Value="PaleVioletRed"/>
        <Setter Property="BorderThickness" Value="0"/>
    </Style>
</ResourceDictionary>

Thus, the dictionary defines a brush constant, and two styles.

In order to use the resource dictionary items in our view, we must modify the Window.Resources element as follows:

XML
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ResourceDictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <System:Double x:Key="ButtonWidth">80</System:Double>
    </ResourceDictionary>
</Window.Resources>

Now we can use the items in the external resource dictionary as if they were defined in the view. For example:

XML
<Border Grid.Row="2" Grid.Column="0" 
Style="{StaticResource borderRedNoLine}">
    <GroupBox Header="Styles Example Two" 
    Style="{StaticResource groupBoxStyleRedBorder}">
        <Label>Styles defined in a dictionary in the application assembly</Label>
    </GroupBox>
</Border>

Using A Resource Dictionary In A Separate Assembly

What if we have multiple applications which want to share the same styles? The answer is simple, we allow them to access a resource dictionary in a shared assembly, typically a class library.

Let's assume that we have created a separate class library called WpfExternalDictionary.dll containing a resource dictionary in a file called ResourceDictionary.xaml located in a folder called View. We add a reference to the file in the Window.Resources element as follows:

XML
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ResourceDictionary.xaml"/>
            <ResourceDictionary Source="pack:
            //application:,,,/WpfExternalDictionary;component/View/ResourceDictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <System:Double x:Key="ButtonWidth">80</System:Double>
    </ResourceDictionary>
</Window.Resources>

The items in the resource dictionary may now be used as if they were defined in the view XAML.

Example Application and Class Library

I have created a simple demonstration application and a separate class library, which illustrate the concepts described above. The link is of course at the start of this article.

History

  • 14th September, 2017: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
C#/WPF/C++ Windows developer

Comments and Discussions

 
QuestionExcellent Article Pin
Member 141914761-Oct-22 6:41
Member 141914761-Oct-22 6:41 
PraiseJust what I was looking for Pin
Member 1435694720-Aug-20 20:19
Member 1435694720-Aug-20 20:19 
QuestionWPF resource dictionary introduction Pin
Member 1468667711-Dec-19 19:46
Member 1468667711-Dec-19 19:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.