改变 TabControl 的背景

Changing background of TabControl

我想更改 WPF TabControl 的背景颜色:

更改 TabControl 的背景颜色不起作用,因为 Grid 元素(TabControl 的直接子元素)不继承其父元素的背景:

下面的代码有效,但它改变了所有后续网格的背景颜色:

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

有没有更合适的解决方案?

在写答案的时候,已经在评论中给出了正确的想法,但无论如何我都会发布完整的例子。

  1. 在您的控件中添加 xmlns:s="clr-namespace:System;assembly=mscorlib" 命名空间。

  2. 将此 ControlTemplate 添加到 xaml 中的 ResourceDictionary 中:

    <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>
    

例如,我为根 Grid 内的 TabPanel 元素设置了 Background="Aqua"

  1. 将这个ControlTemplate赋给TabControl的Template属性:

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