如何在WPF TabControl中为选定的tabItem添加下划线

问题描述 投票:0回答:1

问题

我正在开发一个 WPF 项目,需要有关设计

TabControl
的帮助。

我的主窗口的标题左侧有一个标签,右侧有一个

TabControl
,其中包含三个仅包含图标内容的
TabItems

目标: 如何在选择不同

TabItem
时移动的
TabControl
中为选定的
TabItems
添加下划线?下划线应位于
TabControl

的下边框

代码

<UserControl x:Class="MyProject.Wpf.Views.Header"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             DataContext="{Binding HeaderView, Source={StaticResource Locator}}"
             d:DesignHeight="300" d:DesignWidth="300">
    <Border CornerRadius="6,6,0,0" BorderBrush="#262260" BorderThickness="5" Background="#262260">
        <Grid Background="Transparent">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" HorizontalAlignment="Left" Background="Transparent" Height="32" Margin="16,0,0,0" MouseDoubleClick="Control_OnMouseDoubleClick">
                <Button.Template>
                    <ControlTemplate>
                        <Image HorizontalAlignment="Left" VerticalAlignment="Center" Source="/Images/White.png" />
                    </ControlTemplate>
                </Button.Template>
            </Button>
            <TabControl Grid.Column="2" Background="Transparent" VerticalAlignment="Center"  Margin="10">
                <TabItem IsSelected="True">
                    <TabItem.Header>
                        <Button Command="{Binding ShowPageA}">
                            <Button.Template>
                                <ControlTemplate>
                                    <Image Source="Images/PageA.png" Width="24" Height="24" />
                                </ControlTemplate>
                            </Button.Template>
                        </Button>    
                    </TabItem.Header>
                </TabItem>
                <TabItem>
                    <TabItem.Header>
                        <Button Command="{Binding ShowPageB}">
                            <Button.Template>
                                <ControlTemplate>
                                    <Image Source="/Images/PageB.png" Width="24" Height="24" />
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </TabItem.Header>
                </TabItem>
                <TabItem>
                    <TabItem.Header>
                        <Button Command="{Binding ShowPageC}">
                            <Button.Template>
                                <ControlTemplate>
                                    <Image Source="/Images/PageC.png" Width="24" Height="24" />
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </TabItem.Header>
                </TabItem>
            </TabControl>
        </Grid>
    </Border>
</UserControl>

任何有关如何实现此效果的示例或指导将不胜感激。

c# wpf
1个回答
0
投票

您始终可以覆盖默认模板来添加元素。

另一个不需要重新实现视觉状态行为的解决方案是正确使用模板。

一般来说,您应该使用模板和样式来消除重复的代码。在您的情况下,此重复代码是

TabItem
标头的内容。

使用

RadioButton
(而不是
Button
)还可以改进
TabItem
选择的处理。 A
RadioButton
完美体现了
TabItem
的互斥选择状态。

以下示例演示如何使用

Border
添加红色水平线,方法是为
DataTemplate
属性定义
TabItem.HeaderTemplate
,以及隐式将此模板应用于
 的所有 
Style
 元素的 
TabItem
 TabControl

该示例还展示了如何通过将内联

ControlTemplate
移动到资源字典来消除重复代码。这也改进了按钮的配置,从而提高了代码的可读性。

<TabControl Grid.Column="2"
            Background="Transparent"
            VerticalAlignment="Center"
            Margin="10">
  <TabControl.Resources>
    <DataTemplate x:Key="HeaderTemplate">
      <StackPanel>

        <!-- The host for the header content -->
        <ContentControl Content="{Binding}" />

        <!-- Use a Border as it will naturally stretch to fill the available space dynamically -->
        <Border x:Name="SelectionMarker"
                Background="Red"
                Height="2"
                Visibility="Hidden" />
      </StackPanel>

      <DataTemplate.Triggers>

        <!-- Only show the selection marker when the item is selected -->
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=IsSelected}"
                     Value="True">
          <Setter TargetName="SelectionMarker"
                  Property="Visibility"
                  Value="Visible" />
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>

    <!-- Apply the DataTemplate to all TabItems -->
    <Style TargetType="TabItem">
      <Setter Property="HeaderTemplate"
              Value="{StaticResource HeaderTemplate}" />
    </Style>

    <!-- The exatracted ControlTemplate of each button (now a RadioButton) -->
    <ControlTemplate x:Key="ButtonTemplate"
                     TargetType="RadioButton">

      <!-- Set image source via the Content property of the button -->
      <Image Source="{TemplateBinding Content}"
             Width="24"
             Height="24" />
    </ControlTemplate>

    <!-- Apply the ControlTemplate to all RadioButtons within the TabControl -->
    <Style TargetType="RadioButton">
      <Setter Property="Template"
              Value="{StaticResource ButtonTemplate}" />
      <Setter Property="IsChecked"
              Value="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=IsSelected}" />
      <Setter Property="GroupName"
              Value="TabHeaderSelector" />
    </Style>
  </TabControl.Resources>

  <TabItem IsSelected="True">
    <TabItem.Header>
      <RadioButton Command="{Binding ShowPageA}"
                   Content="Images/PageA.png" />
    </TabItem.Header>
  </TabItem>
  <TabItem>
    <TabItem.Header>
      <RadioButton Command="{Binding ShowPageB}"
                   Content="Images/PageB.png" />
    </TabItem.Header>
  </TabItem>
  <TabItem>
    <TabItem.Header>
      <RadioButton Command="{Binding ShowPageC}"
                   Content="Images/PageC.png" />
    </TabItem.Header>
  </TabItem>
</TabControl>
© www.soinside.com 2019 - 2024. All rights reserved.