In the XAML framework for Windows Store apps, you create a control template when you want to customize a control's visual structure and visual behavior. Controls have many properties, such as Background, Foreground, and FontFamily, that you can set to specify different aspects of the control's appearance. But the changes that you can make by setting these properties are limited. You can use the ControlTemplate class to create a template that provides additional customization. Here we show you how to create a ControlTemplate to customize the appearance of a CheckBox control.
Roadmap: How does this topic relate to others? See:
Custom control template example
By default, a CheckBox control puts its content (the string or object next to the CheckBox) to the right of the selection box. This is the visual structure of the CheckBox. By default, a check mark indicates that a user selected the CheckBox. This is the visual behavior of the CheckBox. You can change these characteristics by creating a ControlTemplate for the CheckBox. For example, suppose that you want the content of the check box to be below the selection box, and you want to use an X to indicate that a user selected the check box. You specify these characteristics in the ControlTemplate of the CheckBox.
Here's a CheckBox using the default ControlTemplate shown in the Unchecked, Checked, and Indeterminate states.

To use a custom template with a control, you assign the ControlTemplate to the Template property of the control. Here's a CheckBox using a ControlTemplate called CheckBoxTemplate1. We show the Extensible Application Markup Language (XAML) for the ControlTemplate in the next section.
<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>
Here's how this CheckBox looks in the Unchecked, Checked, and Indeterminate states after we apply our template.

Specifying the visual structure of a control
When you create a ControlTemplate, you combine FrameworkElement objects to build a single control. A ControlTemplate must have only one FrameworkElement as its root element. The root element usually contains other FrameworkElement objects. The combination of objects makes up the control's visual structure.
This XAML creates a ControlTemplate for a CheckBox that specifies that the content of the control is below the selection box. The root element is a Border. The example specifies a Path to create an X that indicates that a user selected the CheckBox, and an Ellipse that indicates an indeterminate state. Note that the Opacity is set to 0 on the Path and the Ellipse so that by default, neither appear.
<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="25"/> </Grid.RowDefinitions> <Rectangle x:Name="NormalRectangle" Fill="{StaticResource InputControlNormalFillBrush}" Stroke="{StaticResource InputControlStrokeBrush}" StrokeThickness="{StaticResource InputControlStrokeThickness}" UseLayoutRounding="True" Height="21" Width="21"/> <!-- Create an X to indicate that the CheckBox is selected. --> <Path x:Name="CheckGlyph" Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z" Fill="{StaticResource InputControlGlyphBrush}" FlowDirection="LeftToRight" Height="14" Width="16" Opacity="0" Stretch="Fill"/> <!-- Create an Ellipse to indicate that the CheckBox is in an indeterminate state. --> <Ellipse x:Name="IndeterminateGlyph" Fill="{StaticResource ControlGlyphBrush}" Height="12" Width="12" Opacity="0"/> <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" Grid.Row="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> </Border> </ControlTemplate>
Specifying the visual behavior of a control
A visual behavior specifies the appearance of a control when it is in a certain state. The CheckBox control has 3 check states: Checked, Unchecked, and Indeterminate. The value of the IsChecked property determines the state of the CheckBox, and its state determines what appears in the box.
This table lists the possible values of IsChecked, the corresponding states of the CheckBox, and the appearance of the CheckBox.
| IsChecked value | CheckBox state | CheckBox appearance |
| true | Checked | Contains an X. |
| false | Unchecked | Empty. |
| null | Indeterminate | Contains an ellipse. |
You use VisualState objects to specify the appearance of a control when it is in a certain state. A VisualState contains a Storyboard that changes the appearance of the elements in the ControlTemplate. When the control enters the state that the VisualState.Name property specifies, the Storyboard begins. When the control exits the state, the Storyboard stops. You add VisualState objects to VisualStateGroup objects. You add VisualStateGroup objects to the VisualStateManager.VisualStateGroups attached property, which you set on the root FrameworkElement of the ControlTemplate.
This XAML shows the VisualState objects for the Checked, Unchecked, and Indeterminate states. The example sets the VisualStateManager.VisualStateGroups attached property on the Border, which is the root element of the ControlTemplate. The CheckedVisualState specifies that the Opacity of the Path named CheckGlyph (which we show in the previous example) is 1. The IndeterminateVisualState specifies that the Opacity of the Ellipse named IndeterminateGlyph is 1. The UncheckedVisualState has no Storyboard, so the CheckBox returns to its default appearance.
<ControlTemplate TargetType="CheckBox" x:Key="CheckBoxTemplate1"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CheckStates"> <VisualState x:Name="Checked"> <Storyboard> <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckGlyph"/> </Storyboard> </VisualState> <VisualState x:Name="Unchecked"/> <VisualState x:Name="Indeterminate"> <Storyboard> <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="IndeterminateGlyph"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="25"/> </Grid.RowDefinitions> <Rectangle x:Name="NormalRectangle" Fill="{StaticResource InputControlNormalFillBrush}" Stroke="{StaticResource InputControlStrokeBrush}" StrokeThickness="{StaticResource InputControlStrokeThickness}" UseLayoutRounding="True" Height="21" Width="21"/> <!-- Create an X to indicate that the CheckBox is selected. --> <Path x:Name="CheckGlyph" Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z" Fill="{StaticResource InputControlGlyphBrush}" FlowDirection="LeftToRight" Height="14" Width="16" Opacity="0" Stretch="Fill"/> <!-- Create an Ellipse to indicate that the CheckBox is in an indeterminate state. --> <Ellipse x:Name="IndeterminateGlyph" Fill="{StaticResource ControlGlyphBrush}" Height="12" Width="12" Opacity="0"/> <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" Grid.Row="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> </Border> </ControlTemplate>
To better understand how VisualState objects work, consider what happens when the CheckBox goes from the Unchecked state to the Checked state, then to the Indeterminate state, and then back to the Unchecked state. Here are the transitions.
| State transition | What happens | CheckBox appearance when the transition completes |
From Unchecked to Checked. | The Storyboard of the Checked VisualState begins, so the Opacity of CheckGlyph is 1. | An X is displayed. |
From Checked to Indeterminate. | The Storyboard of the Indeterminate VisualState begins, so the Opacity of IndeterminateGlyph is 1.
The Storyboard of the Checked VisualState ends, so the Opacity of CheckGlyph is 0. | An ellipse is displayed. |
From Indeterminate to Unchecked. | The Storyboard of the Indeterminate VisualState ends, so the Opacity of IndeterminateGlyph is 0. | Nothing is displayed. |
Use tools to work with themes easily
A fast way to apply themes to your controls is to right-click on a control on the Visual Studio or Blend design surface and select Edit Theme or Edit Style (depending on the control you are right-clicking on). You can then apply an existing theme by selecting Apply Resource or define a new one by selecting Create Empty.
Related topics
Build date: 11/29/2012