Learn how to skin a Windows Presentation Foundation (WPF) application in Expression Blend.
In this tutorial I will show you how to skin a WPF application in
Expression Blend. The application you'll create will have a very
simple UI but the concepts you'll learn will enable you to skin WPF
applications with more expansive user interfaces.
Skinning is the ability to change the look and feel of an
application and enabling your WPF app to be skinnable involves taking
into account certain factors which you'll familiarize yourself with as
you go along.
Let's start skinning;
- Start Expression Blend and create a new WPF project named
'Skinning'. Ensure that the Language is set to Visual
Basic in the Language combo box.
- Select the Window element in Objects and
Timeline and in the Layout section of the Properties panel set the
width to 400 and height to 300.
- Select the Rectangle tool from the Toolbox and draw out a
rectangle on the window. Set the rectangle's Vertical Alignment to
- Rename the rectangle as 'Header' and give it a
blue gradient Fill. Set its Stroke to No brush.
- Select the Window element and in the Brushes section of the
properties panel set its Background to a gradient brush.
- Select the Button tool and draw a button in the Window
We will skin our app next by changing the current blue look to red.
Skinning involves making use of ResourceDictionaries that contain the
different looks and feels that you'd want for your application. A
ResourceDictionary is basically a collection of resources. A resource
can be any of the properties of an object or, in the case of a control
like a button, a style or a template. For a property to change when you
add a new ResourceDictionary it must be assigned a DynamicResource. A
DynamicResource changes at runtime when you switch from one
ResourceDictionary to another.
If you take a look at the xaml code for the application you notice
that there are no DynamicResources assigned to any of the properties of
the elements in the application. This shall change as we go along.
ResourceDictionaries & Resources
In the following steps we shall create ResourceDictionaries and
- Click on the Resources tab to open the Resources panel and click
on the 'Create new resource dictionary' button.
- In the New Item dialog change the name of the new
ResourceDictionary to BlueSkin.xaml. Click on Ok.
BlueSkin.xaml is added to the list in the Resources panel.
- Select the Window element in Objects and Timeline and open the
- Click on the 'Advanced options' button that is next to the
Background property in the brushes section. Select Convert to
New Resource from the context menu. This opens the Create
Brush Resource dialog.
- In the Create Brush Resource dialog change the name to
'WindowBackground' and select the Resource dictionary
option button. Ensure that you have BlueSkin.xaml as the intended
target in the combo box. Click on Ok.
If you switch to xaml view you will notice that the Background
property of the Window element is assigned a DynamicResource named
- Select the rectangle we added. In the Properties panel click on
the Advanced options button of the Fill property and select 'Convert to
New Resource' from the context menu.
- Name the new resource as 'HeaderFill' and select the 'Resource
dictionary' option button. Click on Ok.
- Select the Resources tab to open the Resources panel. Create a
new Resource Dictionary and name it as
- Select the Window element and change the gradient brush of its
Background to a reddish gradient.
- Click on the 'Advanced options' button of the Background property
and select Convert to new Resource from the context menu.
- In the Create Brush Resource dialog change the name to
'WindowBackground' and select the Resource dictionary option button.
Select RedSkin.xaml from the combo box and click on Ok. Ignore the
If you look in the Resources panel and expand both BlueSkin and
RedSkin.xaml, you notice that both resource dictionaries have resources
with the same name.
Since WindowBackground in BlueSkin is a DynamicResource it will be
swapped with WindowBackground in RedSkin when we change the resource
dictionary. If the names were different there would be no change in the
background color since your application wouldn't know which resource to
apply from the new resource dictionary.
- Select Header in Objects and Timeline and give its Fill a Red
- Click on the 'Advanced options' button of the Fill property and
select Convert to New Resource from the context menu.
- In the 'Create Brush Resource' dialog change the name to
HeaderFill and select the Resource dictionary option button. Select
RedSkin.xaml from the combo box and click on Ok.
Now that we have completed creating our Resource Dictionaries lets
add the necessary coding to enable us to switch to the red skin at
- Select the button we added to our application and in the Properties panel click on the Events button.
- In the Click event textbox type 'Btn1_Click' and press enter. Blend's code editor opens for you to add the necessary code for the button's click event.
- In the Btn1_Click event type in the following code,
Dim RedSkin as New ResourceDictionary
RedSkin.Source = New Uri("RedSkin.xaml", UriKind.Relative)
The code above creates a new resource dictionary named RedSkin and assigns its source property the resource dictionary RedSkin.xaml that we created earlier. We then clear the MergedDictionaries collection and add a new resource dictionary. MergedDictionaries is a collection of ResourceDictionary objects. If you have an application where you want to maintain the link to an existing resource dictionary then avoid clearing the MergedDictionaries collection and instead of using the add method type in the following code,
Me.Resources.MergedDictionaries(0) = RedSkin
This code places the resource dictionary in the first slot of the MergedDictionaries collection.
- Select the Resource panel tab and expand App.xaml.
- Since our application is currently linked to RedSkin.xaml we'll remove this link. Right click 'Linked To: RedSkin.xaml' and select Delete from the context menu. Click on Yes in the resulting dialog box.
- Run the application. Click on the button. Notice that the interface changes to a reddish look.
- Close the application.
So far we have managed to change the look of some of the elements in our application. The button object still looks the same even after we switch skins. Changing the look of a control is slightly different than changing the look of a shape object like a rectangle or ellipse. To change the look of a control object we have to work with either styles or templates.
Styles allow us to change the look of a control but limit us since we can't directly access the elements that make up the control. Templates on the other hand allow us to directly manipulate the elements that make up a control. In a template you can add, delete or modify the elements that make up the overall structure of a control. Therefore when skinning a control you can choose to work with either styles or templates.
Skinning a Control Object
In the following steps we shall skin our button control by using templates.
- Select the button object. Right click the button and select Edit Template > Create Empty.
- In the 'Create ControlTemplate Resource' dialog leave the name as is and select the Resource dictionary option button. BlueSkin.xaml should be the only value in the combo box as we deleted the link to RedSkin. Click on Ok.
- Zoom in on the empty Control Template.
- Draw a rectangle in the empty grid and then right click it and select Auto Size > Fill. The rectangle should fill the whole grid.
- Rename the rectangle as BtnBackground and give it rounded corners.
- In the Properties panel ensure that the Properties button, and not the Events button, is active.B Change the StrokeThickness to 2 and change the stroke color to a white solid brush.
- Select Fill and change it to a blue gradient brush.
- Select the Assets button in the toolbox and select the ContentPresenter in the Controls section of the Assets window. The ContentPresenter is added to the toolbox.
- Double click on the ContentPresenter tool in the toolbox to add it to the control's grid. Set its Horizontal and Vertical alignments to center.
- Draw out another rectangle. Set its stroke to No Brush then adjust it to look like the following image. Turn Off snapping to snaplines if it's giving you a hard time.
- Change both gradient stops to white and adjust the alpha property of the last gradient stop to zero.
- In the Objects and Timeline panel click on the Up One Level button to return back to the Window.
- With the button object selected change its Content property to 'Red' and press enter. Then change its Foreground property to white. Save the project.
- In the Resources panel Right click App.xaml and select Link to ResourceDictionary > RedSkin.xaml. Linking to RedSkin makes it visible in the Resource dictionary combo box of the 'Create ControlTemplate Resource' dialog.
- Select the button. Right click the button and select Edit Template > Edit a Copy.
- In the 'Create ControlTemplate Resource' dialog change the name to ButtonControlTemplate1 and select the Resource dictionary option button and RedSkin.xaml from the combo box. Click on Ok.
- In the button control template change the fill of BtnBackground to a red gradient.
- Return back to the main window. Delete the link to RedSkin.xaml in the App.xaml section of the Resources panel. Click Yes in the resulting dialog.
- Run the project and click on the button. Notice now that all the elements in the application are skinned. A bit of animation would have served our button well to make it look like it's lighting up during mouse over events but you can do that in your free time.
It isn't quite interesting that we can't switch between our two skins so let's enable that.
- Stop the application if you haven't done so.
- Select the button object and copy-paste a new button onto our Window.
- Drag it and place it below the first button.
- Change the Content property of the new button to 'Blue'.
- Select the Events button of the Properties panel and type 'Btn2_Click' in the Click event textbox. Press enter to open the code editor window.
- In the Btn2_Click event procedure type in the following code,
Dim BlueSkin as New ResourceDictionary
BlueSkin.Source = New Uri("BlueSkin.xaml", UriKind.Relative)
- Run the project. Notice that clicking the two buttons allows you to switch between the two skins.
The application is currently opening with the default skin, BlueSkin, when you change the skin and close the application. In order to enable the application to open with the selected skin we shall make use of application settings.
- Right click the project in the Project panel and select Edit in Visual Studio from the context menu.
- Once Visual Studio opens right click the project in Solution Explorer and select Properties from the context menu. This opens the properties window.
- Select the Settings tab. Create a new setting named SkinPath of type String and scope of User. Leave the Value section blank.
- Double click on MainWindow.xaml.vb to open it for editing.
- Select 'MainWindow Events' from the Class Name combo box and Loaded from the Method Name combo box.
- B In the
MainWindow_Loaded event procedure type in the following code,
'Check whether SkinPath has a value and create
'a resource dictionary...
If My.Settings.SkinPath <> String.Empty Then
Dim newDictionary As New ResourceDictionary()
Dim path As String
path = My.Settings.SkinPath
newDictionary.Source = New Uri(path, UriKind.Relative)
- In the
Btn1_Click event procedure add the following code,
My.Settings.SkinPath = "\RedSkin.xaml"
- In the Btn2_Click event procedure add the following code,
My.Settings.SkinPath = "\BlueSkin.xaml"
event procedure we check whether the setting, SkinPath, contains a value and create a resource dictionary whose source property is assigned an uri object that has the setting as the location of a resource dictionary.
In the button click event procedures we assign the setting SkinPath with the location of the relevant resource dictionaries. We then persist the setting by calling the Save method.
- Run the application.
- Change the skin to red and close the application.
- Run the application again. Notice that it now opens with the last skin we had applied.
There are several steps you can take when it comes to skinning user controls.
- When creating your user control you can expose the properties of an element that makes up a control so that once you place the user control on your window you can convert that property into a resource. To do this use dependency properties.
- When creating a user control create resources from the properties of the elements that make up the control i.e. when the user control file is open in Blend select the elements that you want to skin and create resources from the properties of interest.
I hope that the tutorial was of great help but I couldn't finish without taking into account the debate over whether developers should also act as designers. My thought on this is that since Blend offers one the opportunity to put on both hats why not do so. I am of the opinion that there is a developer out there who can also be a good designer and vice versa.