WPF如何自定义TabControl控件样式示例详解

2019-12-30 19:18:56刘景俊

一、前言

程序中经常会用到TabControl控件,默认的控件样式很普通。而且样式或功能不一定符合我们的要求。比如:我们需要TabControl的标题能够居中、或平均分布;或者我们希望TabControl的标题能够进行关闭。要实现这些功能我们需要对TabControl的样式进行定义。

二、实现TabControl的标题平均分布

默认的TabControl标题是使用TabPanel容器包含的。要想实现TabControl标题头平均分布,需要把TabPanel替换成UniformGrid;

替换后的TabControl样式如下:


<Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
  <Setter Property="Padding" Value="2"/>
  <Setter Property="HorizontalContentAlignment" Value="Center"/>
  <Setter Property="VerticalContentAlignment" Value="Center"/>
  <Setter Property="Background" Value="White"/>
  <Setter Property="BorderBrush" Value="#FFACACAC"/>
  <Setter Property="BorderThickness" Value="1"/>
  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
  <Setter Property="Template">
  <Setter.Value>
   <ControlTemplate TargetType="{x:Type TabControl}">
   <Grid x:Name="templateRoot" ClipToBounds="True" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local">
    <Grid.ColumnDefinitions>
    <ColumnDefinition x:Name="ColumnDefinition0"/>
    <ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
    <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
    <RowDefinition x:Name="RowDefinition1" Height="*"/>
    </Grid.RowDefinitions>
    <UniformGrid x:Name="HeaderPanel" Rows="1" Background="Transparent" Grid.Column="0" IsItemsHost="True" Margin="0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
    <Line X1="0" X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" Stroke="White" StrokeThickness="0.1" VerticalAlignment="Bottom" Margin="0 0 0 1" SnapsToDevicePixels="True"/>
    <Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
    <ContentPresenter x:Name="PART_SelectedContentHost" ContentTemplate="{TemplateBinding SelectedContentTemplate}" Content="{TemplateBinding SelectedContent}" ContentStringFormat="{TemplateBinding SelectedContentStringFormat}" ContentSource="SelectedContent" Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Border>
   </Grid>
   <ControlTemplate.Triggers>
    <Trigger Property="TabStripPlacement" Value="Bottom">
    <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/>
    <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
    <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
    </Trigger>
    <Trigger Property="TabStripPlacement" Value="Left">
    <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
    <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
    <Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
    <Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
    <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
    <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
    <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
    </Trigger>
    <Trigger Property="TabStripPlacement" Value="Right">
    <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
    <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
    <Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/>
    <Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
    <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
    <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
    <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
    </Trigger>
    <Trigger Property="IsEnabled" Value="False">
    <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
    </Trigger>
   </ControlTemplate.Triggers>
   </ControlTemplate>
  </Setter.Value>
  </Setter>
 </Style>