Currently I am working on a project where we are building a silverlight line of business application. It’s definitly exciting to see the application take shape, especially since there are so many challenges that I need to face during the development of this application. One of the biggest challenges in this project are bugs in the silverlight toolkit that we use. Although it’s a more or less production version for silverlight 2.0 it is in fact far from bug free.
A good example is the theming support in the form of the ImplicitStyleManager (that is actually coming with silverlight 3.0). It is already featured in the silverlight 2.0 version of the toolkit and what it does is allow you to define several different themes for your application and apply them at runtime at any moment. This is a very cool feature as you can let customers rebrand by letting them choose from a number of themes.
Sounds cool? Yep it is cool, however not if you are creating custom controls and doing all kinds of weird stuff to the default controls in silverlight. The ImplicitStyleManager does not support the kind of work I am doing, the end result is an application that can only be partially themed. That frustrated the @#$ out of me, so I decided to take a peek at how MS build this piece of equipment. As some of you may know, microsoft is delivering the source of silverlight controls on codeplex, so it is actually quite easy to check the implementation out and change it if you require so.
I encountered a couple of places where the ImplicitStyleManager stops working:
- ItemsControls with custom control templates and item templates.
- ContentControl with custom template and styling.
I combined the two into a scenario where I have a ItemsControl with a Canvas as ItemsPanel that has logic to “maximize” a single ItemPanel which is actually a ContentControl wrapped around a user control which is loaded from a separate assemly. You might wonder what I was thinking when I came up with this, but it is actually a pretty standard scenario when you want a cool looking silverlight application.
How does the ImplicitStyleManager work?
What the ImplicitStyleManager does is walk through the visual tree of the application and apply an implicit style to each of the FrameworkElement instances it encounters in the tree. The styles are loaded from a ResourceDictionary that you can specify as the theme of the application. Styles in the resource dictionary don’t need to have a key as long as you keep in mind that a style with a targettype is unique in the resourcedictionary (unless of course you give the second one a key).
Fixing the theming of an ItemsControl and the ContentControl
One of the things that does not work 100% with the ImplicitStyleManager is skinning an ItemsControl. If you search on codeplex you may find that someone posted an issue on the silverlight toolkit project notifying the team that ItemsControl instances are not skinned correctly. There is actually a fix for this that partially solves the problems described in the issue. However it appearantly isn’t fixed enough, because my control still isn’t skinned correctly. This is due to the fact that the VisualTreeHelper (this is a standard utility in silverlight) does not return all items in the visual tree. It stops at the ItemsControl, so the children cannot be skinned by the ImplicitStyleManager.
The core of the problem is the way items in the items control are scoped. The VisualTreeHelper can only retrieve items that are in scope of it. Usually items that have rendering implications in silverlight are in scope, however somehow the item containers in the ItemsControl are not. This limits the options you have for skinning these. Reading the various sources around Microsoft tells me that this might actually be a bug in the runtime. So I really hope they will fix this in version 3.0, otherwise theming will still be messed up in that version of silverlight.
The fix to this problem is actually surprisingly simple: Use an explicit style on the items.
The silverlight toolkit is a great addition to the silverlight framework, even with the known issues that are still in the toolkit. There’s at least 17 components to choose from and 11 themes that come with the toolkit. And although the ImplicitStyleManager is still in the preview band of components it works for at least 90% of the situations.
You can find more information here: http://www.codeplex.com/silverlight