How to: Share Content Among Controls

Microsoft Silverlight will reach end of support after October 2021. Learn more.

This topic explains how to reuse UIElement objects as the content for multiple controls such as Button, RadioButton, and CheckBox. The method described in this topic applies to any control that inherits from ContentControl.

If you want multiple controls to use the same UIElement objects, create a DataTemplate that contains the UIElement. For example, suppose you need multiple buttons on your application to have the same graphic. You can create a DataTemplate that contains the graphic and use it as the ContentTemplate for the buttons.

If you want the buttons to contain both shared elements and unique content, you can add a ContentPresenter to the DataTemplate to specify the location of the unique content and create an empty binding on the Content property of the ContentPresenter by specifying Content="{Binding}". When you specify an empty binding, Content is bound to the control's DataContext. If the Content of the control is set to a CLR object (rather than a UIElement), the object becomes the control's DataContext, so the ContentPresenter displays the Content of the control.

NoteNote:

   Because a ContentPresenter.Content value that is derived from UIElement is not copied to the DataContext, you cannot display UIElement objects as unique content by using a DataTemplate.

Example

The following example creates three buttons that display identical graphics by setting the ContentTemplate of the Button in a Style.

<StackPanel Orientation="Horizontal">
  <StackPanel.Resources>
    <Style x:Key="ArrowButton" TargetType="Button">
      <Setter Property="Margin" Value="5"/>
      <Setter Property="Width" Value="50"/>
      <Setter Property="Height" Value="20"/>
      <Setter Property="ContentTemplate">
        <Setter.Value>
          <DataTemplate>
            <Grid Height="8" Width="8">
              <Path HorizontalAlignment="Stretch" 
                      Margin="0,0,1.8,1.8" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
                      Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/>
              <Path HorizontalAlignment="Stretch" 
                      Margin="2,3,0,0" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
                      Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/>
              <Path HorizontalAlignment="Stretch" 
                      Margin="1.2,1.4,0.7,0.7" 
                      VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" 
                      Data="M2.5,2.5 L7.5,7.5"/>
              <Path HorizontalAlignment="Stretch" 
                      Margin="1.7,2.0,1,1" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
                      Data="M3,7.5 L7.5,7.5 L7.5,3.5"/>
              <Path HorizontalAlignment="Stretch" 
                      Margin="1,1,1,1" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
                      Data="M1.5,6.5 L1.5,1 L6.5,1.5"/>
            </Grid>
          </DataTemplate>
        </Setter.Value>
      </Setter>
    </Style>

  </StackPanel.Resources>
  <Button Style="{StaticResource ArrowButton}"></Button>
  <Button Style="{StaticResource ArrowButton}"></Button>
  <Button Style="{StaticResource ArrowButton}"></Button>
</StackPanel>

The preceding example produces output that is similar to the following illustration.

Buttons that have identical graphics

Three buttons that have the same content.

The following example creates three buttons that display identical graphics and unique content. These buttons can have unique content as well as the shared graphic because the DataTemplate contains a ContentPresenter.

<StackPanel Orientation="Horizontal">
  <StackPanel.Resources>
    <Style x:Key="ArrowButton" TargetType="Button">
      <Setter Property="Margin" Value="5"/>
      <Setter Property="Width" Value="50"/>
      <Setter Property="Height" Value="20"/>
      <Setter Property="ContentTemplate">
        <Setter.Value>
          <DataTemplate>
            <StackPanel Orientation="Horizontal">
              <Grid Height="8" Width="8">
                <Path HorizontalAlignment="Stretch" 
                      Margin="0,0,1.8,1.8" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
                      Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/>
                <Path HorizontalAlignment="Stretch" 
                      Margin="2,3,0,0" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
                      Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/>
                <Path HorizontalAlignment="Stretch" 
                      Margin="1.2,1.4,0.7,0.7" 
                      VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" 
                      Data="M2.5,2.5 L7.5,7.5"/>
                <Path HorizontalAlignment="Stretch" 
                      Margin="1.7,2.0,1,1" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
                      Data="M3,7.5 L7.5,7.5 L7.5,3.5"/>
                <Path HorizontalAlignment="Stretch" 
                      Margin="1,1,1,1" 
                      VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
                      Data="M1.5,6.5 L1.5,1 L6.5,1.5"/>
              </Grid>
              <ContentPresenter Content="{Binding}"/>
            </StackPanel>
          </DataTemplate>
        </Setter.Value>
      </Setter>
    </Style>

  </StackPanel.Resources>
  <Button Style="{StaticResource ArrowButton}" Content="1"></Button>
  <Button Style="{StaticResource ArrowButton}" Content="2"></Button>
  <Button Style="{StaticResource ArrowButton}" Content="3"></Button>
</StackPanel>

The preceding example produces output that is similar to the following illustration.

Buttons that have identical graphics and unique content

Three buttons that have shared and unique content.