Search code examples
wpftabcontrolitemtemplate

WPF Tab Control override template for individual tab content


I have a tab control with some static tabs. However I would also like to add some additional tabs dynamically. Therefore, I defined a header template (using TabControl.ItemTemplate) and a content template (using TabControl.ContentTemplate). However, the static tabs will be showing different content, and therefore I set the individual Tab Item's content template. For some reason however, the Item's content template which I created to set the tab's content is also applying to the header.

You can see from the attached screenshot and code, that while the tab header is set to 'Emails', the tab content is showing up in both the header and the content section.

Please let me know if you need further clarification.

<TabControl Name="ResultsTabControl" SelectionChanged="Selector_OnSelectionChanged" Margin="-2,2" SelectedIndex="{Binding SelectedResultsTab, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

<TabControl.Resources>
    <Style TargetType="TabItem" BasedOn="{StaticResource AccentedMetroTabItemStyle}"></Style>
</TabControl.Resources>

<TabControl.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
    </DataTemplate>
</TabControl.ItemTemplate>

<TabControl.ContentTemplate>
    <DataTemplate>
        <TextBlock Text="Testing"/>
    </DataTemplate>
</TabControl.ContentTemplate>

<TabItem Name="EmailListTab" Header="Emails" Style="{StaticResource AccentedMetroTabItemStyle}">
    <TabItem.ContentTemplate>
        <DataTemplate>
                <TextBlock Text="My Emails Tab"/>
        </DataTemplate>
    </TabItem.ContentTemplate>
</TabItem>

<Style x:Key="AccentedMetroTabItemStyle" TargetType="{x:Type TabItem}">
    <Setter Property="Padding" Value="2 1 2 1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Border x:Name="Border"
                        HorizontalAlignment="Stretch"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                    <StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
                        <StackPanel Margin="{TemplateBinding Padding}" Orientation="Horizontal">
                            <controls1:ContentControlEx x:Name="ContentSite"
                                                       Margin="0 2 2 0"
                                                       Padding="{TemplateBinding Padding}"
                                                       Foreground="{TemplateBinding Foreground}"
                                                       FontSize="15"
                                                       FontWeight="{TemplateBinding controls1:ControlsHelper.HeaderFontWeight}"
                                                       FontStretch="{TemplateBinding controls1:ControlsHelper.HeaderFontStretch}"
                                                       Content="{TemplateBinding Header}"
                                                       ContentCharacterCasing="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls1:ControlsHelper.ContentCharacterCasing)}"
                                                       ContentStringFormat="{TemplateBinding ContentStringFormat}"
                                                       ContentTemplate="{TemplateBinding ContentTemplate}"
                                                       ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                                                       RecognizesAccessKey="True"
                                                       SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                         </StackPanel>
                        <Rectangle x:Name="Underline"
                                   Height="2"
                                   Margin="0 1 0 0"
                                   HorizontalAlignment="Stretch"
                                   Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}, Path=(controls1:TabControlHelper.IsUnderlined), Converter={StaticResource BooleanToVisibilityConverter}}" />
                    </StackPanel>
                </Border>
                <ControlTemplate.Triggers>

                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource AccentColorBrush}" />
                        <Setter TargetName="Underline" Property="Fill" Value="{DynamicResource AccentColorBrush}" />
                    </Trigger>
                    <Trigger Property="IsSelected" Value="false">
                        <Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource GrayNormalBrush}" />
                        <Setter TargetName="Underline" Property="Fill" Value="{DynamicResource GrayNormalBrush}" />
                    </Trigger>
                    <Trigger SourceName="ContentSite" Property="IsMouseOver" Value="True">
                        <Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource GrayHoverBrush}" />
                         <Setter TargetName="Underline" Property="Fill" Value="{DynamicResource GrayHoverBrush}" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition SourceName="ContentSite" Property="IsMouseOver" Value="True" />
                            <Condition Property="IsSelected" Value="True" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource HighlightBrush}" />
                        <Setter TargetName="Underline" Property="Fill" Value="{DynamicResource HighlightBrush}" />
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

TabControl


Solution

  • The thing is that we don't know what happens in the controls1:ContentControlEx.

    And basically you are missing the ContentPresenter for the header in your style:

    <ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    

    It might be part of the controls1:ContentControlEx, but then you have to show that as well.