我们发现自定义 WPF TabControl 的选项卡标题是多么容易,例如添加图像或为文本颜色。但是,如果您希望超越这一点并直接影响选项卡的外观,包括形状和边框,则需要覆盖 TabItem 元素的控件模板,虽然这不像 WPF 的大多数其他区域那样直接,但它是还是可控的。
因此,如果您想完全控制 TabControl 选项卡的外观。
这使得 TabControl 看起来有点像 Windows 8,没有边框和不太微妙的颜色来标记选定的选项卡,并且没有未选定选项卡的背景。所有这些都是通过使用 Style 更改 ControlTemplate 来完成的。通过添加ContentPresenter控件,我们指定了放置 TabItem 内容的位置。我们还有几个触发器,它们根据IsSelected属性控制选项卡的背景颜色 。
先看一下容器TabControl样式代码,TabItem默认设置显示在上面:
<Style TargetType="{x:Type TabControl}">
<Setter Property="TabStripPlacement" Value="Top" />
<Setter Property="Margin" Value="2" />
<Setter Property="Padding" Value="2" />
<Setter Property="Background" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type 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>
<Border x:Name="HeaderBorder"
BorderBrush="Black"
BorderThickness="0"
CornerRadius="5"
Background="#FAFAFA"
Margin="0,0,0,5">
<TabPanel IsItemsHost="True"
Name="HeaderPanel"
Panel.ZIndex="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0" />
</Border>
<Grid Name="ContentPanel"
KeyboardNavigation.TabIndex="2"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
Grid.Column="0"
Grid.Row="1">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5">
<ContentPresenter Content="{TemplateBinding SelectedContent}"
ContentTemplate="{TemplateBinding SelectedContentTemplate}"
ContentStringFormat="{TemplateBinding SelectedContentStringFormat}"
ContentSource="SelectedContent"
Name="PART_SelectedContentHost"
Margin="2"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
/>
</Border>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabControl.TabStripPlacement" Value="Bottom">
<Setter TargetName="HeaderPanel" Property="Grid.Row" Value="1" />
<Setter TargetName="ContentPanel" Property="Grid.Row" Value="0" />
<Setter TargetName="RowDefinition0" Property="RowDefinition.Height" Value="*" />
<Setter TargetName="RowDefinition1" Property="RowDefinition.Height" Value="Auto" />
<Setter TargetName="HeaderBorder" Property="FrameworkElement.Margin" Value="0,5,0,0" />
</Trigger>
<Trigger Property="TabControl.TabStripPlacement" Value="Left">
<Setter TargetName="HeaderPanel" Property="Grid.Row" Value="0" />
<Setter TargetName="ContentPanel" Property="Grid.Row" Value="0" />
<Setter TargetName="HeaderPanel" Property="Grid.Column" Value="0" />
<Setter TargetName="ContentPanel" Property="Grid.Column" Value="1" />
<Setter TargetName="ColumnDefinition0" Property="ColumnDefinition.Width" Value="Auto" />
<Setter TargetName="ColumnDefinition1" Property="ColumnDefinition.Width" Value="*" />
<Setter TargetName="RowDefinition0" Property="RowDefinition.Height" Value="*" />
<Setter TargetName="RowDefinition1" Property="RowDefinition.Height" Value="0" />
<Setter TargetName="HeaderBorder" Property="FrameworkElement.Margin" Value="0,0,5,0" />
</Trigger>
<Trigger Property="TabControl.TabStripPlacement" Value="Right">
<Setter TargetName="HeaderPanel" Property="Grid.Row" Value="0" />
<Setter TargetName="ContentPanel" Property="Grid.Row" Value="0" />
<Setter TargetName="HeaderPanel" Property="Grid.Column" Value="1" />
<Setter TargetName="ContentPanel" Property="Grid.Column" Value="0" />
<Setter TargetName="ColumnDefinition0" Property="ColumnDefinition.Width" Value="*" />
<Setter TargetName="ColumnDefinition1" Property="ColumnDefinition.Width" Value="Auto" />
<Setter TargetName="RowDefinition0" Property="RowDefinition.Height" Value="*" />
<Setter TargetName="RowDefinition1" Property="RowDefinition.Height" Value="0" />
<Setter TargetName="HeaderBorder" Property="FrameworkElement.Margin" Value="5,0,0,0" />
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TabItem样式可以自己调整你自己的风格,我是测试用,随便设置的
<Style TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="#7bbfea" />
<Setter Property="Width" Value="120"/>
<Setter Property="Height" Value="45"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="PART_Border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="LightGray" Margin="0,0,10,0" CornerRadius="10">
<ContentPresenter ContentSource="Header" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" TextBlock.Foreground="#f6f5ec" TextBlock.FontSize="16" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="PART_Border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如果您想要不那么微妙的外观,只需更改模板即可。例如,您可能想要一个边框,但有圆角和渐变背景
下面是调用实例代码:
<TabControl Margin="10" >
<TabItem Header="标签一" />
<TabItem Header="标签二"/>
<TabItem Header="标签二"/>
</TabControl>
推荐一款WPF MVVM框架开源项目:Newbeecoder.UI
Newbeecoder.UI开源项目
Demo下载: