This is something that has bitten me several times, so I thought I’d write it down.  Maybe I’ll remember, and maybe I’ll help others when they hit this too.

The scenario happens when you want to create a new control that can have a template applied to it.  Let’s start with this control definition:

   1: using System;
   2: using System.Windows.Controls;
   3: using System.Windows.Markup;
   4:  
   5: namespace ControlTemplate
   6: {
   7:     [ContentProperty("Content")]
   8:     public class MyTemplatedControl : ContentControl
   9:     {
  10:  
  11:     }
  12: }

Then you create your generic.xaml file under the themes folder, and you add a template for your control.

   1: <ResourceDictionary
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:local="clr-namespace:ControlTemplate">
   5:     
   6:     <Style TargetType="local:MyTemplatedControl">
   7:         <Setter Property="Template">
   8:             <Setter.Value>
   9:                 <ControlTemplate TargetType="local:MyTemplatedControl">
  10:                     <TextBlock Text="This is my custom control template" />
  11:                 </ControlTemplate>
  12:             </Setter.Value>
  13:         </Setter>
  14:     </Style>
  15: </ResourceDictionary>


Then you put your custom control on a page.

   1: <UserControl x:Class="ControlTemplate.Page"
   2:              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:              xmlns:local="clr-namespace:ControlTemplate">
   5:     <Grid x:Name="LayoutRoot" Background="White">
   6:         <local:MyTemplatedControl />
   7:     </Grid>
   8: </UserControl>


When you run the app, you expect to see “This is my custom control template” inside the page, but you don’t.  You get a plain white page.  You start trying all kinds of things, trying to figure out why your textblock isn’t showing up.  Eventually you beat your head against the desk a few times and then ask someone to come look to see what you’re doing wrong.

“You need to set the DefaultStyleKey property on your control.”

“Ahh… I forgot again!”  You add 3 lines of code to your control, run, and poof… it works!  Here’s what your control looks like now:

   1: using System;
   2: using System.Windows.Controls;
   3: using System.Windows.Markup;
   4:  
   5: namespace ControlTemplate
   6: {
   7:     [ContentProperty("Content")]
   8:     public class MyTemplatedControl : ContentControl
   9:     {
  10:         public MyTemplatedControl()
  11:         {
  12:             this.DefaultStyleKey = typeof(MyTemplatedControl);
  13:         }
  14:     }
  15: }


Without setting the DefaultStyleKey property to the control’s own type, the template doesn’t get applied.  Set that property in your constructor and you’re good to go.

Technorati Tags: ,