改变 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>
有没有更合适的解决方案?
在写答案的时候,已经在评论中给出了正确的想法,但无论如何我都会发布完整的例子。
在您的控件中添加 xmlns:s="clr-namespace:System;assembly=mscorlib"
命名空间。
将此 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"
。
将这个ControlTemplate
赋给TabControl的Template
属性:
<TabControl Template="{StaticResource CustomTabControlTemplate}">
...
</TabControl>
我想更改 WPF TabControl 的背景颜色:
更改 TabControl 的背景颜色不起作用,因为 Grid 元素(TabControl 的直接子元素)不继承其父元素的背景:
下面的代码有效,但它改变了所有后续网格的背景颜色:
<TabControl>
<TabControl.Resources>
<Style TargetType="Grid">
<Setter Property="Background" Value="Green" />
</Style>
</TabControl.Resources>
<!-- ... -->
</TabControl>
有没有更合适的解决方案?
在写答案的时候,
在您的控件中添加
xmlns:s="clr-namespace:System;assembly=mscorlib"
命名空间。将此
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"
。
将这个
ControlTemplate
赋给TabControl的Template
属性:<TabControl Template="{StaticResource CustomTabControlTemplate}"> ... </TabControl>