Я пытаюсь создать собственный TabControl
, который поддерживает прокрутку, но сохраняет исходный внешний вид TabControl
, очевидно, за исключением того, что он прокручивается.
Для начала я решил отредактировать копию исходного шаблона TabControl
.
Затем я помещаю ScrollViewer
вокруг TabPanel
. Однако это вызвало небольшую проблему, когда вкладки теперь имеют рамку внизу, когда они выбраны. Это можно увидеть ниже, сравнив нормальный TabControl
и стилизованный TabControl
на изображении.
Сначала я предположил, что это z-индексация средства просмотра прокрутки, но, попробовав разные значения и убедившись, что z-индекс средства просмотра прокрутки и TabPanel
явно выше, чем индекс sz Border
, он не имело значения.
Как я могу добиться того же эффекта, когда внизу выбранной вкладки нет рамки, а она заключена в ScrollViewer
?
< EM> MainWindow.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>
2 ответа
Итак, если мы пойдем, взглянем на ScrollViewer
шаблон стиля обратите внимание, что там есть Border
с заданным для него цветом, который является артефактом, который вы видите.
Мы могли бы войти и отредактировать шаблон стиля ScrollViewer и удалить его .... или для этого случая мы могли бы просто позволить ему сохранить свою границу и переопределить наследование стиля, чтобы в вашем шаблоне вы могли сделать что-то вроде;
<ScrollViewer ...>
<ScrollViewer.Resources>
<Color x:Key="BorderMediumColor">#FFFFFFFF</Color>
</ScrollViewer.Resources>
....
</ScrollViewer>
При этом он должен наследовать этот новый цвет для Border
, который в этом случае я просто сделал белым, или вы можете изменить альфа-канал на «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>
Вы можете попробовать это, чтобы получить настраиваемые закругленные вкладки с синим фоном Что касается прокрутки, scrollviewer должен выполнять свою работу
<TabControl.Resources>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border Name="Border" BorderThickness="1,1,1,1" CornerRadius="4,4,0,0" Margin="2,0" Background="#252e37">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="10,2"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="LightSkyBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="GhostWhite" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.