Windows Phone – skinnable application

1. Introduction

Today, I would like to present my concept of making skinnable application in Windows Phone 7.1. Making a skinnable application in Windows Phone might be a little bit tricky. Unfortunately, WP7 doesn’t support DynamicResource keyword which is a basic tool for making skins in WPF. In order to overcome this inconvenience I decided to write a SkinManager for WindowsPhone.

2. Base view

As I mentioned before, there is no support for using dynamic resources in WP7, therefore, in order to force a control to change style, we have to assign this style in code behind. It is rather obvious that in a single window/control there might be quite a lot of other controls whose style also should be changed. That is why, I decided to write controls iterator first.

In this iterator I used DFS algorithm for searching elements in a tree. Thanks to this piece of code I can take advantage of LINQ’s benefits. In the next step I created base classes for views.

3. SkinManager class

Having prepared basis for skinnable control, let me introduce a custom attribute called the SkinnablePartAttribute

This attribute should decorate custom controls which should have an ability to change theme/skin. As you can see, the SkinnablePartAttribute has a ThemePartName property which holds information about a name of ResourceDictionary where styles for the given control ought to be searched. Now, it is time to take a look at a SkinManager class. The SkinManager class has one public function – ApplySkin

This function iterates through all controls which implement a IViewBase interface – in other words, the function iterates through our custom controls. If a control is decorated with the SkinnablePartAttribue, a new Uri is created based on the information from the ThemePartName property and from the skinName parameter(I assumed that all dictionaries are located in the Themes directory). In the final step, private function also known as the AppySkin function is called. This function looks this way:

Here, all the magic begins. In the first step, current ResourceDictionary is transformed into the standard dictionary. The key of this dictionary is a value of style – a reference to the style object. In the next step, I created a new ResourceDictionary based on the Uri parameter passed to this function. In the last step, another loop over controls is performed. However, this time only controls with the assigned Style property are taken into consideration. Then, if the newStyleDictionary contains a key of given control style we are ready to swap styles.

Entire listing of SkinManager is presented below

4. Example of usage

In order to use the SkinManager it is essential to make some preparation. First of all, you have to create Themes directory in a project. In this directory there must be separate subdirectories for every skin you would like to use. What is more, in these subdirectories you should place all ResourceDictionaries specified in the SkinnablePartAttribute. A sample directory structure is shown in the picture below:
The very last step is to make controls (which should be skinnable) inherit from ViewBase. Here is example of usage

and screenshots of the same view with different skin

skinnable application
skinnable application

5. Controls with dynamically changing content

After some test, it turned out that the mechanism presented above has problems with controls which change their content dynamically. Let me clarify – styling grids, list boxes etc. work fine, however changing row styles and listboxitem styles are not working properly. In order to overcome this problem you must define a style for a specific target type. Here is an example of usage with the listbox:

Windows Phone – skinnable application