c# - XAML TabControl 边框问题
问题描述
我正在尝试制作一个TabControl
支持滚动但保持原始外观和感觉的自定义TabControl
,显然它滚动除外。
首先,我选择编辑使用的原始模板的副本TabControl
。
然后我ScrollViewer
在TabPanel
. However, this has caused a minor issue where the tabs now have a border at the bottom of them when they are selected. 这可以通过比较图像中的法线TabControl
和样式TabControl
在下面看到。
起初我认为这是滚动查看器的 z 索引,但在尝试了不同的值并确保滚动查看器的 z 索引和TabPanel
都明确高于Border
'sz 索引之后,它没有任何区别。
如何在所选选项卡底部没有边框的情况下达到相同的效果,而它被包裹在ScrollViewer
?
主窗口.xaml
<Window x:Class="ScrollableTabControl.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"
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>
<ScrollViewer VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Disabled"
Grid.Column="0"
Grid.Row="0"
Panel.ZIndex="1"
Background="Transparent">
<TabPanel IsItemsHost="true"
Margin="2,2,2,0"
Panel.ZIndex="2"
Background="Transparent"
KeyboardNavigation.TabIndex="1"
x:Name="headerPanel"/>
</ScrollViewer>
<Border x:Name="contentPanel"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Grid.Column="0"
Panel.ZIndex="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>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabControl Margin="5"
Grid.Row="0">
<TabItem Header="Tab 1"/>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
<TabControl Margin="5"
Grid.Row="1"
Style="{DynamicResource TabControlStyle1}">
<TabItem Header="Tab 1"/>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
</Grid>
</Window>
解决方案
因此,如果我们查看ScrollViewer
样式模板,请注意其中有一个Border
带有固定颜色的颜色,这就是您所看到的工件。
我们可以进入并编辑 ScrollViewer 的 Style 模板并将其删除....或者对于这种情况,我们可以让它保留其 Border 并覆盖样式继承,因此在您的模板中您可以执行类似的操作;
<ScrollViewer ...>
<ScrollViewer.Resources>
<Color x:Key="BorderMediumColor">#FFFFFFFF</Color>
</ScrollViewer.Resources>
....
</ScrollViewer>
其中它应该继承那里的新颜色,Border
在这种情况下我只是将其设置为白色,或者您可以将 alpha 通道更改为“00”,因此它只是透明的。或者您可以执行前面提到的操作并定义一个没有硬编码边框值的新样式模板。
希望这会有所帮助,干杯!
附录:如果你找不到导致视觉边界线的罪魁祸首,你总是可以在 DOM 内的元素布局上作弊,并利用边距覆盖线并获得相同的预期视觉效果。从技术上讲,这条线可能仍然存在,但它不能满足的错觉仍然存在。:)
工作代码示例
<Window x:Class="ScrollableTabControl.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"
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"
UseLayoutRounding="True"> <!-- Gets rid of pixel rounding errors which cause small bugs when window is a certain size -->
<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 VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
Grid.Column="0"
Grid.Row="0"
Panel.ZIndex="1"
Margin="0, 0, 0, -1.25"
Background="Transparent"> <!-- +- 1.25 seems to be required when mixed with the ZIndex to hide the border underneath the selected tab -->
<TabPanel IsItemsHost="true"
Margin="2,2,2,1.25"
Background="Transparent"
KeyboardNavigation.TabIndex="1"
x:Name="headerPanel"/>
</ScrollViewer>
<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"
ContentSource="SelectedContent"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabControl Margin="5"
Grid.Row="0">
<TabItem Header="Tab 1"/>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
<TabControl Margin="5"
Grid.Row="1"
Style="{DynamicResource TabControlStyle1}">
<TabItem Header="Tab 1"/>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
</Grid>
</Window>
推荐阅读
- android - 检查热敏打印机中的纸张用完或接近用完状态命令
- javascript - 使用 ember.js 渲染 x3d indexedfacset
- android - 长时间的 Android 构建时间挂在 minify 上
- vector - 每个结构包含结构数组的子集的结构向量的正确模式是什么?
- python - Python 代码昨天运行良好,现在出现“IndexError: list index out of range”
- python - 未找到带有参数“(”,)“的“cart_add”的反向。尝试了 1 种模式:['cart/add/(?P
[0-9]+)/$'] - javascript - 如何防止访问 Google 表单的人将数据复制并粘贴到 word 中?
- php - Laravel 仅更新更改的字段属性
- swift - 从字符串映射到对象参数
- jmeter - 响应消息:非 HTTP 响应消息:未知协议