本文主要是介绍WPF TabControl 滚动选项卡,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 前言
- 相关链接
- TabControl是什么东西
- 通过模板副本查看样式
- IsItemsHost
- 如何修改
- HandyControl的TabControl 滚动
- 总结
前言
我原本以为是很简单的事情,但是没想到实际做起来还是有很多的基础知识点的。
相关链接
WPF 控件库——可拖动选项卡的TabControl
TabControl是什么东西
我们平常写TabControl的时候,可能都很习惯了直接写TabControl+TabItem。但是TabControl负责了什么布局,TabItem负责了什么布局,我们都不知道。
在《深入浅出WPF》中,我们可以看到TabControl属于ItemsControl
通过模板副本查看样式
我们去看看控件模板样式副本。WPF的xaml的优点是每个控件都是单独的逻辑,耦合低。缺点是写起来麻烦,每次改动约等于重新写一个新的。通过增加自己的工作量来降低了耦合
<SolidColorBrush x:Key="TabItem.Selected.Background" Color="#FFFFFF"/><SolidColorBrush x:Key="TabItem.Selected.Border" Color="#ACACAC"/><Style x:Key="TabControlStyle1" TargetType="{x:Type TabControl}"><!--默认基础属性--><Setter Property="Padding" Value="2"/><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Background" Value="{StaticResource TabItem.Selected.Background}"/><Setter Property="BorderBrush" Value="{StaticResource TabItem.Selected.Border}"/><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><!--设置TabItem选项卡的布局--><TabPanel x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/><!--设置TabItem的内容--><Border x:Name="contentPanel" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local"><ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" 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"/><Setter Property="Margin" TargetName="headerPanel" Value="2,0,2,2"/></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"/><Setter Property="Margin" TargetName="headerPanel" Value="2,2,0,2"/></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"/><Setter Property="Margin" TargetName="headerPanel" Value="0,2,2,2"/></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>
我们可以看到中间有个Gird分布,用于声明选项卡和内容之间布局关系。那么哪个代表选项卡,哪个代码【内容】呢?
IsItemsHost
其实选项卡布局还有一个要求,就是得声明【IsItemsHost】这个属性,我们可以看看微软官方文档是怎么说的。
Panel.IsItemsHost 属性
简单来说【IsItemsHost】就是一个可以自动绑定的ItemPanel的声明,ItemPanel是设置ItemControl的布局方式。
如何修改
其实改起来很简单,就是加个【ScrollViewer】就行了。原来的是Panel,我们改成StackPanel这样就不会自动换行了。
<Window x:Class="WpfApp2.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp2"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"><Window.Resources><SolidColorBrush x:Key="TabItem.Selected.Background"Color="#FFFFFF" /><SolidColorBrush x:Key="TabItem.Selected.Border"Color="#ACACAC" /><Style x:Key="TabControlStyle1"TargetType="{x:Type TabControl}"><!--默认基础属性--><Setter Property="Padding"Value="2" /><Setter Property="HorizontalContentAlignment"Value="Center" /><Setter Property="VerticalContentAlignment"Value="Center" /><Setter Property="Background"Value="{StaticResource TabItem.Selected.Background}" /><Setter Property="BorderBrush"Value="{StaticResource TabItem.Selected.Border}" /><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><!--设置TabItem选项卡的布局--><ScrollViewer Height="{TemplateBinding Height}" ><StackPanel x:Name="headerPanel"Background="Transparent"Grid.Column="0"IsItemsHost="True"Margin="2,2,2,0"Grid.Row="0"KeyboardNavigation.TabIndex="1"Panel.ZIndex="1" /></ScrollViewer><!--设置TabItem的内容--><Border x:Name="contentPanel"Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="{TemplateBinding BorderThickness}"Grid.Column="0"KeyboardNavigation.DirectionalNavigation="Contained"Grid.Row="1"KeyboardNavigation.TabIndex="2"KeyboardNavigation.TabNavigation="Local"><ContentPresenter x:Name="PART_SelectedContentHost"ContentSource="SelectedContent"Margin="{TemplateBinding Padding}"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" /><Setter Property="Margin"TargetName="headerPanel"Value="2,0,2,2" /></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" /><Setter Property="Margin"TargetName="headerPanel"Value="2,2,0,2" /></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" /><Setter Property="Margin"TargetName="headerPanel"Value="0,2,2,2" /></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><Style TargetType="TabItem"x:Key="default"><Setter Property="FontSize"Value="50" /></Style></Window.Resources><Grid><TabControl Style="{DynamicResource TabControlStyle1}" TabStripPlacement="Left"><TabItem Header="标题1"Style="{StaticResource default}"></TabItem><TabItem Header="标题2"Style="{StaticResource default}"></TabItem><TabItem Header="标题3"Style="{StaticResource default}"></TabItem><TabItem Header="标题4"Style="{StaticResource default}"></TabItem><TabItem Header="标题5"Style="{StaticResource default}"></TabItem><TabItem Header="标题6"Style="{StaticResource default}"></TabItem><TabItem Header="标题7"Style="{StaticResource default}"></TabItem><TabItem Header="标题8"Style="{StaticResource default}"></TabItem></TabControl></Grid>
</Window>
HandyControl的TabControl 滚动
我们看看HandyControl的代码
我们进到代码里面,可以看到他实现了ContentControl,这里我们就不展开说明了
总结
控件模板是必须要深入了解的。WPF我认为就3+1个难点。控件模板,依赖属性,Binding+WPF 动画。前三个掌握了,基本的静态页面就可以写了。动画属于附加需求,不用动画也可以写的很好看
这篇关于WPF TabControl 滚动选项卡的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!