I have been spending a significant amount of time in Silverlight lately. Silverlight is very young. The base technology is solid but it is not as featured as more mature web technologies like ASP.Net. Being young also means that there are not a lot of 3rd party libraries available for a variety of tasks. So I have been writing a lot of framework and component code for our prototype (and possibly production) code.
After a few attempts at developing a clean user control for what should have been something that is very simple, are started looking at the Silverlight Toolkit source code to see if I could garner any best practices from the work Microsoft is doing.
The Silverlight Toolkit team has done some interesting work setting up their project. Instead of developing the toolkit controls with the standard UserControl base class, they have instead opted to write classes based on ContentControl and other base classes. To pair up XAML with the “code behind” they did something really interesting. They engineered a pre-compile task to take XAML resource dictionaries and combine them into one resource dictionary for the project, the so called “generic.xaml” dictionary that provides styles and templates to control libraries (think DLL). I won’t go into a thorough explanation on this page (though I do explain the basic below), but I would invite you to check out the source code and take a look at the explanation of how it all worked here.
It really cleaned up my code. The Silverlight Toolkit approach eliminates a lot of C# code and replaces it with declarative markup. This is a good thing because C# code can have bugs, where declarative markup usually works or it doesn’t. One must test for edge cases in C#, markup usually works or it doesn’t. Get get the picture. That, and for my specific cases it eliminated some really horrible code patterns. The patterns are much simpler now:
- Write dependency properties and their associated ROC (Regular Old Class) properties to represent various items that need to be represented or displayed in UI. For example, child components, styles, colors, brushes, text, etc, would all be loaded into DPs.
- Initialize DPs through ROCs in the control constructor with the default values.
- Set the DefaultStyleKey of the control to the type of the control.
- Template the control with a style/control template combo in a resource dictionary that will get compiled into the DLL. The Style will be wired up to the control because the TargetType is used as the default style key set in #3. Use the TemplateBinding XAML markup to bind the the DPs.
- Rinse, repeat.
The first controls I developed were with the traditionaly “Silverlight User Control” template were full of spaghettie code trying to manage child controls. Since then I have used the Silverlight Toolkit approach, and I have been writing much better code.
