DayPath Journal

Customizing XAML Buttons? Prepare to Repeat Yourself!

Vector Based Button Violating the DRY Principle

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 the StaticResource markup extension (and Silverlight does not support DynamicResource).
  • The vsm:VisualStateManager.VisualStateGroups element cannot be shared in a Style (even though you can see Setter 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 has ContentTemplate and Template properties. Explaining the differences between these two properties makes a smashing interview question (hint: one of these properties uses a DataTemplate for its type).
  • ControlTemplate lives to fill the Control.Template property.
  • ContentControl represents a “single piece” of visualized data—a metaphorical ‘picture’ for the ContentPresenter picture frame.

Related Resources