WPF FAQ - Templates

Find answers for the most frequently asked questions
Expand All Collapse All

The following code shows how the content template can be created and applied to a content control.

[XAML]
<DataTemplate x:Key='template1'>
  <TextBlock Text='{Binding}' FontSize='12' FontWeight='Bold' TextWrapping='Wrap'></TextBlock>
</DataTemplate>

The above code can be applied as follows.

[XAML]

<Button ContentTemplate='{StaticResource template1}' Content='Click'>
Permalink

This can be done as follows.

[XAML]

<Style x:Key='ContentCtrl' TargetType='ContentControl'>
    <Setter Property='Background' Value='Red'/>
    <Setter Property='Foreground' Value='Green'/>
    <Setter Property='FontSize' Value='20'/>
    <Setter Property='FontWeight' Value='Bold'/>
    <Setter Property='Template'>
        <Setter.Value>
            <ControlTemplate TargetType='ContentControl'>
                <Grid>
                    <Ellipse Width='{TemplateBinding Width}' Height='{TemplateBinding Width}' Fill='{TemplateBinding Background}'/>
                    <ContentPresenter VerticalAlignment='Center' HorizontalAlignment='Center'/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

...

<ContentControl Width='75' Height='100' Style='{StaticResource ContentCtrl}' Content='Hello'/>
Permalink

You can create a template programatically by populating the VisualTree of the template.

[C#]
			DataTemplate template = new DataTemplate();

			template.VisualTree = new FrameworkElementFactory(typeof(Path));

			template.VisualTree.SetBinding(Path.StrokeProperty, new Binding('Stroke'));
			template.VisualTree.SetBinding(Path.StrokeThicknessProperty, new Binding('StrokeThickness'));
			template.VisualTree.SetBinding(Path.FillProperty, new Binding('Interior'));
			template.VisualTree.SetBinding(Path.DataProperty, new Binding('Geometry'));

Permalink

Getting hold of an element in a ControlTemplate is very easy, as this article explains:

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

Sample code:


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

But, if want to get hold of an item in a DataTemplate (which gets applied for each item in the ItemsControl), then there is more code involved as explained here:

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

Sample Code:


// Note that the ListBox must have
// IsSynchronizedWithCurrentItem set to True for this to work
ListBoxItem myListBoxItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));
ContentPresenter myContentPresenter = FindVisualChild(myListBoxItem);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName('textBlock', myContentPresenter);
Permalink

ControlTemplate can be created for a HeaderedItemsControl as follows.

[XAML]

<!--Define a control template for a HeaderedItemsControl-->
<Style TargetType='HeaderedItemsControl'>
  <Setter Property='Template'>
    <Setter.Value>
      <ControlTemplate TargetType='{x:Type HeaderedItemsControl}'>
        <StackPanel>
          <Grid>
            <Rectangle Fill='{TemplateBinding Background}'/>
            <ContentPresenter ContentSource='Header'/>
          </Grid>
          <Grid>
            <Rectangle Stroke='{TemplateBinding BorderBrush}'/>
            <ItemsPresenter Margin='2,0,0,0'/>
          </Grid>
        </StackPanel>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

...

<HeaderedItemsControl  xmlns:sys='clr-namespace:System;assembly=mscorlib'
                       Header='My colors'
                       Background='SteelBlue'
                       BorderBrush='DarkSlateBlue'>
  <sys:String>Red</sys:String>
  <sys:String>Yellow</sys:String>
  <sys:String>Blue</sys:String>
  <sys:String>Green</sys:String>
</HeaderedItemsControl>
Permalink

The example Extensible Application Markup Language (XAML) version could use the <Button.Content> tags around the content of each button, but it is not necessary. The Four buttons can be created as follows.

[XAML]

<!--Create a Button with a string as its content.-->
<Button>This is string content of a Button</Button>

<!--Create a Button with a DateTime object as its content.-->
<Button xmlns:sys='clr-namespace:System;assembly=mscorlib'>
  <sys:DateTime>2004/3/4 13:6:55</sys:DateTime>
</Button>

<!--Create a Button with a single UIElement as its content.-->
<Button>
  <Rectangle Height='40' Width='40' Fill='Blue'/>
</Button>

<!--Create a Button with a panel that contains multiple objects 
as its content.-->
<Button>
  <StackPanel>
    <Ellipse Height='40' Width='40' Fill='Blue'/>
    <TextBlock TextAlignment='Center'>Button</TextBlock>
  </StackPanel>
</Button>
Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.