Changing background of TabControl

238 views Asked by At

I would like to change the background color of a WPF TabControl: enter image description here

Changing the background color of the TabControl does not work, because the Grid element (direct child of the TabControl) doesn't inherit the backround of its parent: enter image description here

The code below works, but it changes the background color of all subsequent grids:

<TabControl>
    <TabControl.Resources>
        <Style TargetType="Grid">
            <Setter Property="Background" Value="Green" />
        </Style>
    </TabControl.Resources>
    <!-- ... -->
</TabControl>

Is there a more appropriate solution?

1

There are 1 answers

0
Sam On BEST ANSWER

While writing answer, nkoniishvt has already given right idea in comments, but I anyway will finish posting complete example.

  1. Add xmlns:s="clr-namespace:System;assembly=mscorlib" namespace in your control.

  2. Add this ControlTemplate in your ResourceDictionary in xaml:

    <ControlTemplate x:Key="CustomTabControlTemplate"  TargetType="TabControl" >
        <Grid ClipToBounds="True" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Name="ColumnDefinition0" />
                <ColumnDefinition Width="0" Name="ColumnDefinition1" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" Name="RowDefinition0" />
                <RowDefinition Height="*" Name="RowDefinition1" />
            </Grid.RowDefinitions>
            <TabPanel IsItemsHost="True" Name="HeaderPanel" Margin="2,2,2,0" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1" Grid.Column="0" Grid.Row="0" Background="Aqua" />
            <Border BorderThickness="{TemplateBinding Border.BorderThickness}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="ContentPanel" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Column="0" Grid.Row="1">
                <ContentPresenter Content="{TemplateBinding TabControl.SelectedContent}" ContentTemplate="{TemplateBinding TabControl.SelectedContentTemplate}" ContentStringFormat="{TemplateBinding TabControl.SelectedContentStringFormat}" ContentSource="SelectedContent" Name="PART_SelectedContentHost" Margin="{TemplateBinding Control.Padding}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
            </Border>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="TabControl.TabStripPlacement">
                <Setter Property="Grid.Row" TargetName="HeaderPanel">
                    <Setter.Value>
                        <s:Int32>1</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Row" TargetName="ContentPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="RowDefinition.Height" TargetName="RowDefinition0">
                    <Setter.Value>
                        <GridLength>*</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="RowDefinition.Height" TargetName="RowDefinition1">
                    <Setter.Value>
                        <GridLength>Auto</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="FrameworkElement.Margin" TargetName="HeaderPanel">
                    <Setter.Value>
                        <Thickness>2,0,2,2</Thickness>
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <x:Static Member="Dock.Bottom" />
                </Trigger.Value>
            </Trigger>
            <Trigger Property="TabControl.TabStripPlacement">
                <Setter Property="Grid.Row" TargetName="HeaderPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Row" TargetName="ContentPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Column" TargetName="HeaderPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Column" TargetName="ContentPanel">
                    <Setter.Value>
                        <s:Int32>1</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="ColumnDefinition.Width" TargetName="ColumnDefinition0">
                    <Setter.Value>
                        <GridLength>Auto</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="ColumnDefinition.Width" TargetName="ColumnDefinition1">
                    <Setter.Value>
                        <GridLength>*</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="RowDefinition.Height" TargetName="RowDefinition0">
                    <Setter.Value>
                        <GridLength>*</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="RowDefinition.Height" TargetName="RowDefinition1">
                    <Setter.Value>
                        <GridLength>0</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="FrameworkElement.Margin" TargetName="HeaderPanel">
                    <Setter.Value>
                        <Thickness>2,2,0,2</Thickness>
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <x:Static Member="Dock.Left" />
                </Trigger.Value>
            </Trigger>
            <Trigger Property="TabControl.TabStripPlacement">
                <Setter Property="Grid.Row" TargetName="HeaderPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Row" TargetName="ContentPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Column" TargetName="HeaderPanel">
                    <Setter.Value>
                        <s:Int32>1</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="Grid.Column" TargetName="ContentPanel">
                    <Setter.Value>
                        <s:Int32>0</s:Int32>
                    </Setter.Value>
                </Setter>
                <Setter Property="ColumnDefinition.Width" TargetName="ColumnDefinition0">
                    <Setter.Value>
                        <GridLength>*</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="ColumnDefinition.Width" TargetName="ColumnDefinition1">
                    <Setter.Value>
                        <GridLength>Auto</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="RowDefinition.Height" TargetName="RowDefinition0">
                    <Setter.Value>
                        <GridLength>*</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="RowDefinition.Height" TargetName="RowDefinition1">
                    <Setter.Value>
                        <GridLength>0</GridLength>
                    </Setter.Value>
                </Setter>
                <Setter Property="FrameworkElement.Margin" TargetName="HeaderPanel">
                    <Setter.Value>
                        <Thickness>0,2,2,2</Thickness>
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <x:Static Member="Dock.Right" />
                </Trigger.Value>
            </Trigger>
            <Trigger Property="UIElement.IsEnabled">
                <Setter Property="TextElement.Foreground">
                    <Setter.Value>
                        <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <s:Boolean>False</s:Boolean>
                </Trigger.Value>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

For example I set Background="Aqua" for TabPanel element inside root Grid.

  1. Assign this ControlTemplate to the Template property of TabControl:

    <TabControl Template="{StaticResource CustomTabControlTemplate}">
        ...
    </TabControl>