Search code examples
wpfxamltriggerscontroltemplatetabitem

Setting the color of the TabItem header's foreground when the tab is clicked and not clicked


I have this TabControl in my application:

<TabControl Width="100" Height="100">
    <TabControl.Resources>
        <Style TargetType="{x:Type TabItem}" x:Key="TabItemStyle">
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Border x:Name="Chrome"
                                BorderBrush="Blue" 
                                Background="Transparent">
                            <ContentPresenter ContentSource="Header"
                                              Margin="0,0,0,3"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Selector.IsSelected" Value="True">
                                <Setter TargetName="Chrome" Property="BorderThickness" Value="0,0,0,3"/>
                            </Trigger>
                            <Trigger Property="Selector.IsSelected" Value="False">
                                <Setter TargetName="Chrome" Property="BorderThickness" Value="0,0,0,0"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.Resources>

    <TabItem Style="{DynamicResource TabItemStyle}">
        <TabItem.Header>
             <Label Content="Tab 1" />
        </TabItem.Header>
    </TabItem>

    <TabItem Style="{DynamicResource TabItemStyle}">
        <TabItem.Header>
             <Label Content="Tab 2" />
        </TabItem.Header>
    </TabItem>
</TabControl>

When I click a tab in the TabControl, a blue line is displayed below the tab header.
This is beside the point, but I'm sure the style I have will be useful.

In the tab headers there are labels.
I would like to change the foreground of labels according to:

  • When the tab is clicked, the label's foreground should be Red.
  • When the tab is not clicked, the label's foreground should be Gray.

I assume I can use the trigger I already have in the ControlTemplate to determine when the tab was clicked or not.

But I don't know what I need to do to set the labels foreground accordingly in the style.


Solution

  • You could create a DataTemplate as HeaderTemplate and use a DataTrigger that sets the Foreground color of the Labels depending on the selection state of the containing TabItems, which is bound using a RelativeSource. The separate header template also reduces the redundancy in your TabItems, because you do not have to define the Label in each time again.

    <TabControl Width="100"
                Height="100">
       <TabControl.Resources>
          <Style TargetType="{x:Type TabItem}"
                 x:Key="TabItemStyle">
             <Setter Property="VerticalContentAlignment"
                     Value="Stretch" />
             <Setter Property="HorizontalContentAlignment"
                     Value="Stretch" />
             <Setter Property="HeaderTemplate">
                <Setter.Value>
                   <DataTemplate>
                      <Label x:Name="TabItemHeaderLabel" Foreground="Gray" Content="{Binding}" />
                      <DataTemplate.Triggers>
                         <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" Value="True">
                            <Setter TargetName="TabItemHeaderLabel" Property="Foreground" Value="Red"/>
                         </DataTrigger>
                      </DataTemplate.Triggers>
                   </DataTemplate>
                </Setter.Value>
             </Setter>
             <Setter Property="Template">
                <Setter.Value>
                   <ControlTemplate TargetType="{x:Type TabItem}">
                      <Border x:Name="Chrome"
                              BorderBrush="Blue"
                              Background="Transparent">
                         <ContentPresenter ContentSource="Header"
                                           Margin="0,0,0,3"
                                           HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                           VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                      </Border>
                      <ControlTemplate.Triggers>
                         <Trigger Property="Selector.IsSelected"
                                  Value="True">
                            <Setter TargetName="Chrome"
                                    Property="BorderThickness"
                                    Value="0,0,0,3" />
                         </Trigger>
                         <Trigger Property="Selector.IsSelected"
                                  Value="False">
                            <Setter TargetName="Chrome"
                                    Property="BorderThickness"
                                    Value="0,0,0,0" />
                         </Trigger>
                      </ControlTemplate.Triggers>
                   </ControlTemplate>
                </Setter.Value>
             </Setter>
          </Style>
       </TabControl.Resources>
    
       <TabItem Style="{DynamicResource TabItemStyle}"
                Header="Tab 1"/>
    
       <TabItem Style="{DynamicResource TabItemStyle}"
                Header="Tab 2"/>
    </TabControl>