How do I programmatically interact with template-generated elements? Part I

You may have a scenario that requires you to find an element within a ControlTemplate. To do that, you use Template.FindName.

Say you have a simple ControlTemplate for a Button, like the following:

    <Style TargetType="{x:Type Button}">

      <Setter Property="Template">

        <Setter.Value>

          <ControlTemplate TargetType="{x:Type Button}">

            <Grid Margin="5" Name="grid">

              <Ellipse Stroke="DarkBlue" StrokeThickness="1">

                <Ellipse.Fill>

                  <RadialGradientBrush Center="0.3,0.2"

                                       RadiusX="0.5" RadiusY="0.5">

                    <GradientStop Color="Azure" Offset="0.1" />

                    <GradientStop Color="CornflowerBlue"

                                  Offset="1.1" />

                  </RadialGradientBrush>

                </Ellipse.Fill>

              </Ellipse>

              <ContentPresenter Name="content" Margin="10"

                                HorizontalAlignment="Center"

                                VerticalAlignment="Center"/>

            </Grid>

          </ControlTemplate>

        </Setter.Value>

      </Setter>

    </Style>

Thanks to the TargetType attribute, the ControlTemplate is automatically applied to this Button:

<Button Name="myButton1" Margin="10"

        Click="ControlTemplateFindElement">Find Grid in ControlTemplate</Button>

Button ControlTemplate

If you need to find a named element in the ControlTemplate of myButton1, like the Grid, you can use Template.FindName like so:

// Finding the grid generated by the ControlTemplate of the Button

Grid gridInTemplate = (Grid)myButton1.Template.FindName("grid", myButton1);

 

Just for fun, let’s create a message box that shows the actual width of that grid:

// Do something with the ControlTemplate-generated grid

MessageBox.Show("The actual width of the grid in the ControlTemplate:"

   + gridInTemplate.GetValue(Grid.ActualWidthProperty).ToString());

Grid in Template Message Box

Calling Template.FindName works here, but in some cases you may have to write a bit more code. In Part II, I’ll show you how to find an element that’s generated by the DataTemplate of a ListItem (which is also generated). A sample that shows both scenarios will also be in the next refresh of the SDK docs.