Using app.xaml and ResourceDictionaries for Cleaner WPF Customisation

When I first started making WPF forms, I was using PowerShell. This was a good starting point I think as I felt really comfortable with PowerShell which let me experiment more freely and break things in a way that I still felt comfortable.

However, this also meant putting all of my XAML into a single string. This might not sound too bad, but when you have five buttons all with slightly different templates and behaviours, the code quickly becomes messy and hard to read. Note that XAML is easy to read in the first place 😫 I was no stranger to having code that looked like this:

<Border Grid.Column="0" Grid.Row="1" Background="#FFE87E31" HorizontalAlignment="Right" Width="25" Height="25" Margin="0,0,2,0" CornerRadius="20"  BorderBrush="White" BorderThickness="1">
                <Label Name="Search_Button" Cursor="Hand" Foreground="White" Content="🔍" FontSize="12" Width="25" Height="27" Margin="-1.667,-1.667,-0.334,-0.334" />
            </Border>
<!-- OBJECT PANEL AND OBJECTS -->
            <Border HorizontalAlignment="Stretch" Grid.Column="0" Grid.Row="2" VerticalAlignment="Stretch" Background="#FF34495F" >
                <ScrollViewer VerticalScrollBarVisibility="Auto">
                    <StackPanel>
        <!-- ALL OPTION OBJECTS HERE -->
                        <Border Height="35">
                            <Border.Style>
                                <Style>
                                    <Setter Property="Border.Background" Value="#FF34495F"/>
                                    <Style.Triggers>
                                        <Trigger Property="Border.IsMouseOver" Value="True">
                                            <Setter Property="Border.Background" Value="#FF1F2A36" />
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </Border.Style>
                            <Label Name="General_Information_Button" Cursor="Hand" VerticalContentAlignment="Center" Foreground="White" Content="General Information" FontFamily="Century Gothic" FontSize="14" />
                        </Border>

Horrible I know…

But when I moved to use C# with WPF, I found that I could have separate resources that could be used by multiple controls at the same time. You do this by adding a resource dictionary to the app.xaml file inside the WPF project.

Here is a quick example of what I mean. I created a Styles folder in the root of my WPF project and added a new ResourceDictionary(WPF). I called this resource dictionary “TextStyles” and it looks like this:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FontSize" Value="28"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
</ResourceDictionary>

Perfect, I then added this to my app.xaml file which now looks like this:

<Application x:Class="WPFUI.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WPFUI">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Styles/TextStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

From now on, all the text blocks in the WPF application would use the Arial font, use font size 28, be bold and also be white.

Important Notes:

  1. It’s important to add your resource dictionaries to the app.xaml file in the correct order. You want to work from top to bottom. Meaning you don’t want a resource dictionary using something from another resource dictionary below it. For example, if you are using custom colours and want your text blocks to be that colour, you would put your colour resource first and then your text block resource.
  2. If you don’t want a resource to be used everywhere in your application if you style inside the resource dictionary a name. Then you can reference the style inside your WPF XAML code.

Enjoy!


Leave a Reply