Customizing XAML Buttons? Prepare to Repeat Yourself!
Customizing XAML buttons in particular and XAML Controls in general almost immediately lead to violating the Don’t Repeat Yourself (DRY) principle. I am glad that I did not try to seriously customize buttons earlier in my Silverlight/WPF journey because the by-design depth of this problem would have seriously discouraged me from continuing with this technology.
This violation of DRY is, to me, due to the fact that the ControlTemplate
cannot be completely composed out of smaller, reusable resources because:
- Any Visual State Manager
Storyboard
elements cannot be shared with theStaticResource
markup extension (and Silverlight does not supportDynamicResource
). - The
vsm:VisualStateManager.VisualStateGroups
element cannot be shared in aStyle
(even though you can seeSetter Property="vsm:VisualState…"
in IntelliSense). - I thought declaring
<Grid VisualStateManager.CustomVisualStateManager …>
would help but nothing came from this.
What’s long-term educational about this unpleasantness is using this experience to really, really learn about the differences among Control
, ControlTemplate
, ContentControl
and ContentPresenter
. So as of this morning I understand that:
Control
is a “useless” XAML element in Silverlight because it cannot be used (it’s an abstract class in Silverlight).ContentControl
hasContentTemplate
andTemplate
properties. Explaining the differences between these two properties makes a smashing interview question (hint: one of these properties uses aDataTemplate
for its type).ControlTemplate
lives to fill theControl.Template
property.ContentControl
represents a “single piece” of visualized data—a metaphorical ‘picture’ for theContentPresenter
picture frame.