Shareable and Customizable SVG Resources in WPF

Having spent most of my time doing web development, when I was asked to add some scalable vector graphics (SVGs) into our WPF application, I thought, “No problem! That will be quick.”

Naturally, I was getting ahead of myself. While adding SVGs into our WPF windows wasn’t too painful overall, it took a little more than simply adding an SVG to a webpage.

Resources for SVGs

I had a few goals in mind when determining how to add the icons to our application. First, I wanted them to be available across several windows. Second, I wanted to avoid having SVG path data cluttering up any window XAML unnecessarily. And lastly, I wanted the icons to be able to hook into our existing resources for colors so they could be easily themed if desired.

To accomplish this, I starting by adding a new resource dictionary called Icons.xaml to the project. It starts off looking pretty normal:


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyApp">
</ResourceDictionary>

Let’s say you want to add in the exclamation triangle icon from Font Awesome. First, you need to download the SVG. Then, open it in your favorite text editor and find the <path> element and its d property. In our exclamation triangle icon, this starts with M569.517 .... Copy that entire value for the next step.

Now, go back to the Icons.xaml resource dictionary. In this, add a new PathGeometry element, with the Figures property set to the d value we copied in the previous step. The resource dictionary should now look something like this (path data is truncated for readability):


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyApp">
    <PathGeometry x:Key="Exclamation" Figures="M569.517 440.013C5..." />
</ResourceDictionary>

Now, we have the path information available as a resource. By storing just a path, we can choose which color to fill it with each time we render it, allowing us to use the icon in different UI elements.

Color Resources

As mentioned previously, I wanted to have a set of color resources available to easily change font and icon colors in the future. For this, I simply created another resource dictionary called Colors.xaml. It is a simple collection of Color elements, like the following:


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyApp">
    <Color x:Key="Blue" R="0x00" G="0x8C" B="0xFF" A="0xFF" />
</ResourceDictionary>

With both of our resource dictionaries ready to go, it’s time to add an icon to our window!

Using Path Resources in a Window

Before using the colors or icons directly in the XAML, we are going to need to add the resource dictionaries to the window’s resources. We accomplish this using MergedDictionaries like so:


<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Icons.xaml" />
            <ResourceDictionary Source="Colors.xaml" />
        </ResourceDictionary.MergedDictionaries>

        <SolidColorBrush x:Key="BlueBrush" Color="{StaticResource Blue}" />
    </ResourceDictionary>
</Window.Resources>

I have also declared a new resource in the window for a brush that uses our blue color.

Now, to add in an icon, there’s not much more we need to do. All we need are a few elements: a Canvas, a Viewbox, and a Path. Together, they look like this:


<Canvas Width="16" Height="16">
    <Viewbox Width="16" Height="16">
        <Path Data="{StaticResource Exclamation}" Fill="{StaticResource BlueBrush}" />
    </Viewbox>
</Canvas>

The Canvas and Viewbox are used to control the size of the icon on the window. The Path element is where we can put in the path icon and color information. To do that, use a StaticResource combined with the key of the resource you wish to use. These keys correspond to the x:Key property on each of the resources we defined.

That’s It!

Not too bad, eh? Once you have a set of icon resources available, you can easily add them all across your WPF application without worrying about copying lengthy path data all over the place.

I hope this guide has aided you in your SVG icon adventures! Please leave a comment below if you have any other tips or tricks for using SVGs in WPF applications.