XAML TabControl Border Issues - PullRequest
       8

XAML TabControl Border Issues

0 голосов
/ 23 октября 2018

Я пытаюсь создать пользовательский TabControl, который поддерживает прокрутку, но сохраняет первоначальный внешний вид TabControl, очевидно, за исключением того, что он прокручивается.

Для начала я решил отредактироватьИспользуется копия оригинального шаблона TabControl.

Затем я ставлю ScrollViewer вокруг TabPanel.Однако это вызвало небольшую проблему, когда у вкладок теперь есть граница внизу, когда они выбраны.Это можно увидеть ниже, сравнив обычный TabControl и стилизованный TabControl на изображении.

Сначала я предположил, что это было z-индексированием средства просмотра с прокруткой, но после пробования других значений и проверкиИндекс z средства просмотра прокрутки и TabPanel явно выше, чем индекс Border 'sz, это не имеет значения.

Как добиться того же эффекта, когда в нижней части рамки нет границы?выбранная вкладка, пока она обернута в ScrollViewer?

enter image description here


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 ]

0 голосов
/ 23 октября 2018

Итак, если мы пойдем, взглянем на шаблон стиля 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>
0 голосов
/ 23 октября 2018

Вы можете попробовать это, чтобы получить пользовательские закругленные вкладки с синим фоном Что касается прокрутки, 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>
...