I like using tools like Microsoft Expression Design or Blend to create the vector graphics for my visuals. And while the XAML created by these tools is perfectly valid and reasonable I tend to find myself wanting to clean it up a bit to make my code eaiser to read and maintain. Many times I have an element like a Button that shares a styled control template with other Buttons and the only thing that differs between them all is the path used to create the button image icon in the middle of the button.
The problem is, how do we take a button like this:
and easily swap out the visual element in the middle for other buttons so that they each have their own unique visual.
One technique would be to create a keyed style for each type of button and simply reference the style on each button. This however means one style for each button and if you have a lot of buttons, this can really increase the size of your resource file and doesn’t do much for ease of tracking down a particular style when you need to make changes. Also, changes to other aspects of the control template across all buttons means making a change to all styles. A maintainence nightmare.
A second technique would be to subclass the Button control and create a dependency property that you can set to a Path object in your XAML representing the visual you want on your button. Hopefully you should already be shaking your head at the thought of dipping into C# to create a coded solution to a visual problem.
The technique I propose uses one style for the button and style triggers to swap out the path used by the button based on the content of the button. Isn’t this what style triggers are useful for, changing visuals based on some criteria? You don’t have to use the content as the differentiator, you can use any property value you can think of.
So let’s get started.
When you export the XAML of a visual from Expression Design you get something like this:
Which is a path used to create this visual:

In the XAML above, the only thing we really care about is the path data which we can harvest and store in a keyed PathGeometry resource element like so:
The path data is a collection of all the point information used to render the path on the screen. It’s a mathematical description of the shape of our path excluding any color information which we can add later.
Now we can create a simple button template:
Note in the above control template the Path named “iconpath” has it’s data set to the static resource key of our PathGeometry data we harvested from our Expression Design visual that was exported to XAML. Note also that we set the Fill of the path to a static brush resource which paints our shape whatever color we choose.
I’ve excluded some brush and color information for brevity but assuming you have some brushes and colors, this style gives us a button that looks like this:

Now that we have this set up, we can create more visuals in our vector creation tool and more keyed PathGeometry resources:
Now the question is, how do we swap between these geometries so that we can have individual buttons with their own visuals but sharing the same style? We can add triggers to determine which PathGeometry we should use based on the content of the button. So we add this to our control template in the button style:
And this is how we declare our buttons in our Window:
Now the triggers will inspect the content value and swap out the Path data with the appropriate keyed resource which gives us what we ultimately want:

The full source for this example is available here: Dynamic Button Visuals Source Code
Enjoy!