1

I have the following HeaderTemplate for an Expander:

<Expander.HeaderTemplate>
    <DataTemplate>
        <Grid Background="#939393">
            <Grid.RowDefinitions>
                <RowDefinition Height="22"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.Resources>
                <Style TargetType="{x:Type ToggleButton}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ToggleButton}">
                                <Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="border" CornerRadius="5,5,5,5" 
                                        Background="Transparent" BorderBrush="#FF000000" Margin="1" BorderThickness="1,1,1,1" SnapsToDevicePixels="True">
                                    <ContentPresenter x:Name="contentPresenter"/>
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsChecked" Value="true">
                                        <Setter Property="Background" TargetName="border" Value="DarkGray"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Grid.Resources>
            <TextBlock Grid.Column="0" Background="#6E6E6E"/>
            <ToggleButton Grid.Column="0" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" Focusable="False">
                <Image Source="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}, Converter={StaticResource boolToExpanderDirectionConverter}}"/>
            </ToggleButton>
            <TextBlock Grid.Column="1" Text="General" Margin="5,1,1,1" VerticalAlignment="Top" FontWeight="Bold"/>
        </Grid>
    </DataTemplate>
</Expander.HeaderTemplate>

This Headertemplate I have defined directly at one Expander. Now I want to move this Template to a Resource and apply it to all Expanders. My problem now is, that I don't know how to set the Header of the TextBlock in the Template to the Header of the Expander.

I knwo there's a way with TemplateBinding, but unfortunately I don't know how to use this.

Tomtom
  • 9,087
  • 7
  • 52
  • 95

3 Answers3

2

TemplateBinding can only be used within a ControlTemplate.TemplateBinding is used for binding to the element properties within the template definition..

here in your example you have used controltemplate for toggleButton.

Example For TemplateBinding

   <Style TargetType="{x:Type ToggleButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                            <ContentPresenter TextElement.Foreground="{TemplateBinding Foreground}" x:Name="contentPresenter"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            .....
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
    </Style>

<ToggleButton Grid.Column="0" Background="Red" BorderBrush="Black" BorderThickness="1" Foreground="White"/>

Here Border and Contentpresnter will bind properties of ToggleButton that is alreday defined in its defination.


But in your example you used Datatemplate..so you cant use TemplateBinding ..Please Follow This link for Binding Syntax.

Solution For Your example

Using Binding syntax we can bind Header property to different exapnder Text="{Binding Path=Header,RelativeSource={RelativeSource AncestorType={x:Type Expander}}}"

  <Window.Resources>
    <DataTemplate x:Key="ExpanderHeaderTemplate">
        <Grid Background="#939393">
            <Grid.RowDefinitions>
                <RowDefinition Height="22"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.Resources>
                <Style TargetType="{x:Type ToggleButton}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ToggleButton}">
                                <Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="border" CornerRadius="5,5,5,5" 
                                    Background="{TemplateBinding Background}" BorderBrush="#FF000000" Margin="1" BorderThickness="1,1,1,1" SnapsToDevicePixels="True">
                                    <ContentPresenter x:Name="contentPresenter"/>
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsChecked" Value="true">
                                        <Setter Property="Background" TargetName="border" Value="DarkGray"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Grid.Resources>
            <TextBlock Grid.Column="0" Background="#6E6E6E"/>
            <ToggleButton Grid.Column="0" Background="Red" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" Focusable="False">
                <Image Source="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}, Converter={StaticResource boolToExpanderDirectionConverter}}"/>
            </ToggleButton>
            <TextBlock Grid.Column="1" Text="{Binding Path=Header,RelativeSource={RelativeSource AncestorType={x:Type Expander}}}" Margin="5,1,1,1" VerticalAlignment="Top" FontWeight="Bold"/>
        </Grid>
    </DataTemplate>
</Window.Resources>

 <StackPanel>
    <Expander Header="General1" HeaderTemplate="{StaticResource ExpanderHeaderTemplate}"/>
    <Expander Header="General2" HeaderTemplate="{StaticResource ExpanderHeaderTemplate}"/>
</StackPanel>


   
Community
  • 1
  • 1
Heena
  • 8,450
  • 1
  • 22
  • 40
0

you can have a idea of Template binding by below code i had implemented this when i was learning XAML.

<Button Template="{DynamicResource CircleButton}" Background="Green" Content="1"></Button>

<ControlTemplate x:Key="CircleButton" TargetType="{x:Type Button}">
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center" MinHeight="36" MinWidth="36">
            <Ellipse Fill="{TemplateBinding Background}"></Ellipse>
            <ContentPresenter TextBlock.FontFamily="Calibri" TextBlock.FontSize="24" TextBlock.Foreground="Wheat" HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
        </Grid>

you have to give a x:Key to control Template and when you are binding it with some specific element define that x:key there like i did Template="{DynamicResource CircleButton}".

following is your case:

<Style  TargetType="{x:Type Expander}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Expander}">
                     // Do your thing.
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

this will apply to all Expander throught your application. You can put this Style into App.xaml file for code cleanness. hope this'll help you.

Deeps
  • 330
  • 1
  • 5
  • 16
0

Since you are specifying a HeaderTemplate via a DataTemplate, the DataContext of the template IS the Header. This simple example works:

<Expander Header="Test">
    <Expander.HeaderTemplate>
        <TextBlock Text="{Binding}"/>
    </Expander.HeaderTemplate>
</Expander>
Roel van Westerop
  • 1,400
  • 8
  • 17