WPF自定义TabControl选项滚动条显示
一、TabControl简介
TabControl控件是WPF中常用的可以切换不同窗口、页面和空间的实现选项卡功能的控件,根据微软文档对它的介绍,继承关系如下
FrameworkElement——Control——ItemsControl——Selector——TabControl
TabControl为 ItemsControl ,这意味着它可以包含任何类型的对象的集合 (例如字符串、图像或面板) 。
二、自定义TabControl控件
TabControl控件默认的控件样式或功能有时不一定满足我们的需求,这时我们可以对其进行自定义,设置style属性,修改默认值 ControlTemplate。
有关自定义的详细信息可以浏览微软官方文档,ControlTemplate ,请参阅通过创建 System.windows.controls.controltemplate> 自定义现有控件的外观。 若要查看特定于的部分和状态,请参阅TabControl 样式和模板。
三、自定义TabControl选项滚动条显示
当给TabControl控件添加多个TabItem时,如果是将选项位置即TabStripPlacement属性设置为Left,那么当数量较多时窗口会无法显示全部选项,这时就需要使用滚动条来显示全部选项。
在WPF中要实现滚动条显示一般是使用ScrollViewer控件,而TabControl选项即标题区域是使用TabPanel容器包含的,因此思路就是自定义TabControl样式,然后在标题区域外面加上一个ScrollViewer,Xaml实现代码如下:
<Window.Resources>
<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>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TabPanel x:Name="HeaderPanel" Background="Transparent" Grid.Column="0" IsItemsHost="True" Margin="0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
</ScrollViewer>
<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>
</Window.Resources>
style样式需要在Window.Resources内定义,定义好样式后,在后面添加TabControl控件是需要引用定义的样式,代码如下:
<TabControl x:Name="ImageTab" TabStripPlacement="Left" Style="{StaticResource TabControlStyle}"/>
参考文档
TabControl 类
WPF 自定义TabControl控件样式
WPF自定义TabControl样式
WPF-TabControl 选项卡
WPF自适应可关闭的TabControl 类似浏览器的标签页