Powered by

US - English
NEW! Silverlight 5 is available Learn More

Control Templates

By Microsoft Silverlight Team|March 5, 2009|Level 300 : Intermediate

Summary

In Silverlight, 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. However, 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. This QuickStart shows how to create a ControlTemplate to customize the appearance of a CheckBox control.

This QuickStart contains the following sections:

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 the CheckBox is selected. 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 above the selection box, and you want to use an X to indicate that the check box is selected. You specify these characteristics in the ControlTemplate of the CheckBox.

The following example shows a CheckBox with the default ControlTemplate and a CheckBox with a custom ControlTemplate. To try this example, click the check boxes multiple times to see the Checked, Unchecked, and Indeterminate states.

Control Template Sample Download

You can download the Control Template sample from the following location.

Download this sample

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.

The following XAML creates a ControlTemplate of a CheckBox that specifies that the content of the control is above the selection box. The example specifies a Path to create an X that indicates that the CheckBox is selected, 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.

XAML

 
<ControlTemplate TargetType="CheckBox">
  <StackPanel x:Name="Root" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center">
   <!--The ContentPresenter displays the Content 
        property of the CheckBox.  Content can be any 
        type of object.-->    <ContentPresenter/>
    <!--Draw the selection indicator area.-->    <Border Width="30" Height="30" 
      BorderBrush="Black" 
      BorderThickness="1" CornerRadius="0" 
      HorizontalAlignment="Left"
      Background="{TemplateBinding Background}" 
      Padding="2" >

      <Grid>
        <!--Create an X to indicate that the 
               CheckBox is selected.-->        <Path x:Name="Checkmark" 
          Opacity="0" Stroke="#FF313030"
          Margin="-10.5,-6.8,-10.5,-6" 
          RenderTransformOrigin="0.5,0.5" 
          Fill="#FFE0E0E0" Stretch="Fill"
          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" >

          <Path.RenderTransform>
            <TransformGroup>
              <ScaleTransform ScaleX="0.5" 
                ScaleY="0.5"/>
            </TransformGroup>
          </Path.RenderTransform>
        </Path>
        <!--Create an Ellipse to indicate that 
            the CheckBox is in an indeterminate 
            state.-->        <Ellipse x:Name="IndeterminateEllipse" 
          Opacity="0"
          Fill="#FFE0E0E0" Stroke="#FF313030"
          StrokeThickness="0.5" 
          Margin="1.5,1.9,1.5,1.4">
        </Ellipse>
      </Grid>
    </Border>
  </StackPanel>
</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 three states: Checked, Unchecked, and Indeterminate. The value of the CheckBox.IsChecked property determines the state of the CheckBox, and its state determines what appears in the box.

The following 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 that are in the ControlTemplate. When the control enters the state that is specified by the VisualState.Name property, 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.

The following XAML shows the VisualState objects for the Checked, Unchecked, and Indeterminate states. The example sets the VisualStateManager.VisualStateGroups attached property on the StackPanel, which is the root element of the ControlTemplate. The Checked VisualState specifies that the Opacity of the Path named Checkmark (which is shown in the previous example) is 1. The Indeterminate VisualState specifies that the Opacity of the Ellipse named IndeterminateEllipse is 1. The Unchecked VisualState has no Storyboard, so the CheckBox returns to its default appearance.

XAML

<ControlTemplate TargetType="CheckBox">
  <StackPanel x:Name="Root" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center">

    <vsm:VisualStateManager.VisualStateGroups>
      <vsm:VisualStateGroup x:Name="CheckStates">

        <vsm:VisualStateGroup.Transitions>
          <vsm:VisualTransition 
            GeneratedDuration="0:0:.2" />
        </vsm:VisualStateGroup.Transitions>

        <vsm:VisualState x:Name="Unchecked"/>

        <vsm:VisualState x:Name="Checked">
          <Storyboard>
            <DoubleAnimation 
              Storyboard.TargetName="Checkmark" 
              Storyboard.TargetProperty="Opacity" 
              Duration="0" To="1"/>
          </Storyboard>
        </vsm:VisualState>

        <vsm:VisualState x:Name="Indeterminate">
          <Storyboard>
            <DoubleAnimation 
              Storyboard.TargetName=
                "IndeterminateEllipse" 
              Storyboard.TargetProperty="Opacity" 
              Duration="0" To="1"/>
          </Storyboard>
        </vsm:VisualState>

      </vsm:VisualStateGroup>
    </vsm:VisualStateManager.VisualStateGroups>

    <!--The visual structure of ControlTemplate, 
        which is shown in the previous example, 
        is defined here.-->
    ...
  </StackPanel>
</ControlTemplate>

To better understand how VisualState objects work, consider what occurs when the CheckBox goes from the Unchecked state to the Indeterminate state, then to the Checked state, and then back to the Unchecked state. The following table describes these transitions.

 
State transition What occurs CheckBox appearance when the transition completes
From Unchecked to Indeterminate. The Storyboard of the Indeterminate VisualState begins, so the Opacity of IndeterminateEllipse is 1. An X is displayed.
From Indeterminate to Checked. The Storyboard of the Checked VisualState begins, so the Opacity of Checkmark is 1. The Storyboard of the Indeterminate VisualState ends, so the Opacity of IndeterminateEllipse is 0. An ellipse is displayed.
From Checked to Unchecked. The Storyboard of the Checked VisualState ends, so the Opacity of Checkmark is 0. Nothing is displayed.

See Also

Microsoft Silverlight Team

By Microsoft Silverlight Team, Silverlight is a powerful development platform for creating engaging, interactive user experiences for Web, desktop, and mobile applications when online or offline.

Comments (0)