Using Merged ResourceDictionaries in Silverlight Themes

July 29th, 2009

Silverlight 3.0 moved its featureset closer to that of WPF by adding support for merged Resource Dictionaries and Style Inheritance. Without these features, developing custom templates and styles for Silverlight controls can become a bit of a copy-and-paste nightmare. Since I have used the implicit theming feature built into the Silverlight Toolkit to make my Silverlight controls fit into the overall look and feel of this site, I was hoping that these features would enable me to refactor my themes developed for Silverlight 2.0 to be a bit less unwieldy.

Silverlight toolkit themes do not support merged dictionaries

Unfortunately, merged dictionaries are not supported by the Silverlight Toolkit’s Themes feature – at least not as it stands. For example, the following XAML and accompanying class causes a XamlParseException if you try to use it.

All is not lost however, since full source code is provided for the Silverlight Toolkit, so it becomes a straightforward matter to track down the problem and supply a patch.

Writing a test to reproduce the problem

Since the toolkit comes with an accompanying test suite, we proceed in textbook TDD fashion by first writing a test that exercises the issue. We can reuse some of the existing code to do this, adding a resource dictionary containing a merged dictionary reference and adding the following test to the ImplicitStyleManagerTest class

The test fails as we would expect.

Figure : The test written to exercise the bug fails as expected.

Fix the code to make the test pass

The Theme class works by transforming the ResourceDictionary xaml into a ContentControl. A quick glance at the xaml generated by this process in the Visual Studio debugger shows why an exception is being raised.

The ResourceDictionary.MergedDictionaries element is missing its parent ResourceDictionary element, so we add a couple of lines of code to ResourceParser.ParseElement to detect the element and wrap it in a ResourceDictionary, using LINQ to XML.

Having made the change, we rerun the test.

Figure : How I love the green bar

As we would hope, our custom theme now works as expected and we also have a unit test that ensures the bug does not reoccur. Note the Xaml code above, in that the Resource Dictionary is referenced using Pack Uri syntax. This is because Button.xaml is compiled as a Resource, rather than Content, since the latter doesn’t appear to work reliably and can result in obfuscated error messages such as XamlParseException: attribute “Button.xaml” value out of range.

Figure : The button on the right gets its theme from a merged ResourceDictionary

I have submitted the patch for this fix to the toolkit site on Codeplex.

4 Responses to “Using Merged ResourceDictionaries in Silverlight Themes”

  1. Chris Maduro Says:

    Is this why I cannot implicitly style controls in silverlight without using the ISM(implicit style manager) from the toolkit?
    Should I just not declare a merged dictionary in the app.xaml file. This resource dictionary is from the toolkit, and does not have any x:Key elements. And Silverlight would implicitly style the controls? Or do I have to explicitly state Style=”{StaticResouce MyStyle}” on every single control????

  2. Andrew Says:

    Hi Chris.

    In response to your question – not exactly. Silverlight, unlike WPF, simply doesn’t support implicit styles out of the box – you have to use the ISM from the toolkit in order to support this. The issue covered in this post is how to get the ISM to work with merged dictionaries.

    If you don’t use the ISM, merged dictionaries will work fine, but as you say you will have to explicitly state the style you want to use on each control.

    Cheers,
    Andrew.

  3. GA Says:

    Hi Andrew,

    Thanks for the great info. Do you happen to know if this is still a problem with the Nov 2009 release? I would think so since I saw no release notes to address the issue but I wanted to see if perhaps you know for sure. Also, do you happen to know if the ISM bug about explicit style settings being overwritten by ISM has been resolved in the Nov 2009 release? I am debating whether or not to use ISM for a new theme based SL3 project I am working on. Given SL4 native support for implicit styles and ISM’s issue, I am wondering if perhaps I should just use explit style always, at least for now until SL4 is released.

    Thanks again for your knowledge that you share.

    Cheers

    GA

  4. Andrew Says:

    Thanks for your comment.
    So far as I know the issue still exists since no comment has been made on the issue at
    http://silverlight.codeplex.com/WorkItem/View.aspx?WorkItemId=3427,
    but I haven’t tried the latest release with SL3 since I’ve now moved to SL4b development.

    Best of luck,
    Andrew.

Leave a Reply

Spam Protection by WP-SpamFree