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>


          <ControlTemplate TargetType={x:Type Button}>

            <Grid Margin=5 Name=grid>

              <Ellipse Stroke=DarkBlue StrokeThickness=1>


                  <RadialGradientBrush Center=0.3,0.2

                                       RadiusX=0.5 RadiusY=0.5>

                    <GradientStop Color=Azure Offset=0.1 />

                    <GradientStop Color=CornflowerBlue

                                  Offset=1.1 />




              <ContentPresenter Name=content Margin=10










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.

Comments (12)

  1. Tanveer Badar says:

    What did you people do what that horrible ellipse? It has no antialiasing even on Windows Vista. Terrible fringes.

  2. wcsdkteam says:

    Hi Tanveer, thanks for the feedback! First of all, we’re looking at the PNG of a screenshot here. Also, anti-aliasing is actually in place. For more information regarding rendering and anti-aliasing in WPF, please see

  3. This post shows you how to find a named element within a DataTemplate. In Part I , we discussed how to

  4. jelical says:

    Well, how can I do this from XAML?

       <ControlTemplate x:Key="Expanded"  TargetType="{x:Type HeaderedContentControl}">

         <StackPanel x:Name="contentPanel">

           <ContentPresenter Name="HeaderKey" ContentSource="Header"/>

           <ContentPresenter ContentSource="Content"/>



       <Style x:Key="{x:Type HeaderedContentControl}"

           TargetType="{x:Type HeaderedContentControl}">

         <Setter Property="Template" Value="{StaticResource Expanded}"/>

         <Setter Property="Height" Value="{Binding ElementName=HeaderKey,Path=ActualHeight}" />

         <Setter Property="Width" Value="{Binding ElementName=HeaderKey,Path=ActualWidth}" />

    …(rest of the code omitted)

    This code not working because of bad databinding. How can I access ContentPresenter’s ActualHeight and ActualWidth

  5. wcsdkteam says:

    Hi Jelical,

    It seems like you are trying to bind the ActualWidth and ActualHeight of the ContentPresenter inside the template to the Width and Height values on the HeaderedContentControl (that the template is applied to). If that’s the case, then you should use TemplateBinding.

    It would be something like:

    <ContentPresenter Name="HeaderKey" ActualWidth="{TemplateBinding Width}" ContentSource="Header"/>

    There’s a brief discussion of TemplatingBinding here:

    Hope that help, please let me know if that doesn’t work for you!

  6. jelical says:

    Thanks, but no 🙂 It is upside down. I want to bind HeaderedContentControl size to actual size of its header.

  7. wcsdkteam says:

    Hi Jelical, if what you’re trying to do is to let the Header determine the width and height of the control, then you can do this:

    <Style x:Key="{x:Type HeaderedContentControl}" TargetType="HeaderedContentControl">

     <Setter Property="Template">


         <ControlTemplate TargetType="HeaderedContentControl">

           <StackPanel Height="{Binding ElementName=HeaderPresenter, Path=ActualHeight}"

                       Width="{Binding ElementName=HeaderPresenter, Path=ActualWidth}">

             <ContentPresenter ContentSource="Header" Name="HeaderPresenter"/>

             <ContentPresenter ContentSource="Content"/>






    (I combined your template and style to make it more concise here.)

    You may already know, but in case you’re interested, there’s also an Expander control:

    Hope that helps.

  8. avi_subs says:

    Can we do the same for Datatemplates as well?

  9. Zuff says:

    I need some help.

    <Style x:Key="{x:Type local:HSChart}" TargetType="{x:Type local:HSChart}">        

           <Setter Property="Template">


                   <ControlTemplate TargetType="{x:Type local:HSChart}">

                       <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">

           <Grid x:Name="grid">


                <Canvas Width="8600" Height="4200" x:Name="drawingArea">

                   <Polygon Points="700,150 7900,150 7900,3750 700,3750 700,150" Fill="#FFFFFFF1" />                                    


    I need suggestion on how to access "drawingArea" from the

    public class HSChart : Control{


      private void doSomething(){

          Canvas c = this.Template.FindName("drawingArea", this);



    my c is always null.

    How do I access the named element in xaml?

    Thanks and Best Regards,

    Zuff  😀

  10. Hi Zuff,

    When does doSomething execute?  You can get the elements from the template only after OnApplyTemplate is called, so if you’re calling doSomething in the constructor, the template won’t be applied to the control yet.  You can try overriding OnApplyTemplate, call base.OnApplyTemplate, and then get the named element.  Let me know if that helps.



  11. Zuff says:

    Hi Carole,

       Thanks for your help.

       I managed to get it working after I moved the doSomething() from  the constructor. 😀

       Hope you have a nice weekend 😀

    Best Regards,