Files
ShrlAlgoToolkit/AntDesignWPF/Controls/TabControl.xaml

311 lines
20 KiB
Plaintext
Raw Normal View History

2025-07-31 20:12:24 +08:00
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:AntDesignWPF.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:helpers="clr-namespace:AntDesignWPF.Helpers">
<!--#region 默认样式-->
<Style x:Key="Ant.TabItem" TargetType="{x:Type TabItem}">
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.TextPrimary}"/>
<Setter Property="Padding" Value="12,10"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<!--默认是 Top/Bottom 的样式,下划线-->
<Border x:Name="Border"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0,0,0,2"
Padding="{TemplateBinding Padding}">
<ContentPresenter x:Name="ContentSite"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Header"/>
</Border>
<ControlTemplate.Triggers>
<!--鼠标悬停效果-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.Primary}"/>
</Trigger>
<!--选中效果-->
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.Primary}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource AntDesign.Brush.Primary}"/>
</Trigger>
<!--根据父级 TabControl 的 TabStripPlacement 动态调整下划线位置-->
<DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom">
<Setter TargetName="Border" Property="BorderThickness" Value="0,2,0,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left">
<Setter TargetName="Border" Property="BorderThickness" Value="0,0,2,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right">
<Setter TargetName="Border" Property="BorderThickness" Value="2,0,0,0"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TabControl 样式 (已修正为使用 DockPanel)-->
<Style x:Key="Ant.TabControl" TargetType="{x:Type TabControl}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource Ant.TabItem}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<DockPanel x:Name="templateRoot" KeyboardNavigation.TabNavigation="Local" LastChildFill="True">
<!--标签头容器 (默认停靠在顶部)-->
<Border x:Name="HeaderPanelBorder"
DockPanel.Dock="Top"
BorderBrush="{DynamicResource AntDesign.Brush.BorderPrimary}"
BorderThickness="0,0,0,1">
<TabPanel x:Name="HeaderPanel"
IsItemsHost="True"
Margin="0"
Panel.ZIndex="1"/>
</Border>
<!--内容区域 (自动填充剩余空间)-->
<Border x:Name="ContentPanelBorder"
Background="{TemplateBinding Background}"
BorderThickness="0" >
<ContentPresenter x:Name="PART_SelectedContentHost"
ContentSource="SelectedContent"
Margin="{TemplateBinding Padding}"/>
</Border>
</DockPanel>
<ControlTemplate.Triggers>
<!--当标签在底部时-->
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter TargetName="HeaderPanelBorder" Property="DockPanel.Dock" Value="Bottom"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="0,1,0,0"/>
</Trigger>
<!--当标签在左侧时-->
<Trigger Property="TabStripPlacement" Value="Left">
<Setter TargetName="HeaderPanelBorder" Property="DockPanel.Dock" Value="Left"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="0,0,1,0"/>
</Trigger>
<!--当标签在右侧时-->
<Trigger Property="TabStripPlacement" Value="Right">
<Setter TargetName="HeaderPanelBorder" Property="DockPanel.Dock" Value="Right"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="1,0,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
<Style x:Key="Antd.TabControl" TargetType="{x:Type TabControl}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<DockPanel x:Name="templateRoot" KeyboardNavigation.TabNavigation="Local" LastChildFill="True">
<!--标签头容器 (默认停靠在顶部)-->
<Border x:Name="HeaderPanelBorder"
DockPanel.Dock="Top"
Background="Transparent"
BorderBrush="{DynamicResource AntDesign.Brush.BorderPrimary}"
BorderThickness="0,0,0,1"
Padding="0">
<TabPanel x:Name="HeaderPanel" IsItemsHost="True" Margin="0" Panel.ZIndex="1"/>
</Border>
<!--内容区域 (自动填充剩余空间)-->
<Border x:Name="ContentPanelBorder"
Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource AntDesign.Brush.BorderPrimary}"
BorderThickness="0">
<ContentPresenter x:Name="PART_SelectedContentHost"
ContentSource="SelectedContent"
Margin="{TemplateBinding Padding}"/>
</Border>
</DockPanel>
<ControlTemplate.Triggers>
<!--==================== 基础方向触发器 ====================-->
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter TargetName="HeaderPanelBorder" Property="DockPanel.Dock" Value="Bottom"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="0,1,0,0"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter TargetName="HeaderPanelBorder" Property="DockPanel.Dock" Value="Left"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="0,0,1,0"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter TargetName="HeaderPanelBorder" Property="DockPanel.Dock" Value="Right"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="1,0,0,0"/>
</Trigger>
<!--==================== Card 样式触发器 ====================-->
<DataTrigger Binding="{Binding (helpers:TabControlHelper.TabType), RelativeSource={RelativeSource Self}}" Value="Card">
<!--卡片模式下,内容区有边框和背景-->
<Setter TargetName="ContentPanelBorder" Property="BorderThickness" Value="1"/>
<Setter TargetName="ContentPanelBorder" Property="Background" Value="#FFFFFF"/>
<!--卡片模式下Header区有特殊背景和边距-->
<Setter TargetName="HeaderPanelBorder" Property="Background" Value="#FAFAFA"/>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="0,0,0,1"/>
<Setter Property="Padding" Value="16"/>
</DataTrigger>
<!--卡片模式 + 底部-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding (helpers:TabControlHelper.TabType), RelativeSource={RelativeSource Self}}" Value="Card"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource Self}}" Value="Bottom"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="HeaderPanelBorder" Property="BorderThickness" Value="0,1,0,0"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<!--TabItem 统一模板,根据附加属性切换样式-->
<Style TargetType="{x:Type TabItem}">
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.TextPrimary}"/>
<Setter Property="Padding" Value="12,10"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="ItemBorder"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0,0,0,2"
SnapsToDevicePixels="True"
Padding="{TemplateBinding Padding}">
<StackPanel Orientation="Horizontal">
<ContentPresenter x:Name="ContentSite"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Header"/>
<!--关闭按钮,默认隐藏-->
<Button x:Name="CloseButton"
Style="{DynamicResource Antd.Button.CloseTab}"
Margin="8,0,-4,0"
Visibility="Collapsed"
Command="{Binding DataContext.CloseTabCommand, RelativeSource={RelativeSource AncestorType=TabItem}}"
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TabItem}}"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<!--通用:鼠标悬停-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.Primary}"/>
</Trigger>
<!--通用:选中状态-->
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.Primary}"/>
</Trigger>
<!--==================== Line Style Triggers (默认) ====================-->
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="{DynamicResource AntDesign.Brush.Primary}"/>
</Trigger>
<DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom">
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="0,2,0,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left">
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="0,0,2,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right">
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="2,0,0,0"/>
</DataTrigger>
<!--==================== Card Style Triggers ====================-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding (helpers:TabControlHelper.TabType), RelativeSource={RelativeSource AncestorType=TabControl}}" Value="Card"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="1,1,1,0"/>
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="Transparent"/>
<Setter Property="Margin" Value="0,0,-1,0"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding (helpers:TabControlHelper.TabType), RelativeSource={RelativeSource AncestorType=TabControl}}" Value="Card"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="ItemBorder" Property="Background" Value="#FFFFFF"/>
<Setter TargetName="ItemBorder" Property="BorderThickness" Value="1,1,1,0"/>
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="{DynamicResource AntDesign.Brush.BorderPrimary}"/>
<Setter TargetName="ItemBorder" Property="Margin" Value="0,0,-1,-1"/>
<!--选中时ZIndex更高以覆盖邻居的边框-->
<Setter Property="Panel.ZIndex" Value="1"/>
</MultiDataTrigger>
<!--==================== Editable Style Triggers ====================-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding (helpers:TabControlHelper.IsEditable), RelativeSource={RelativeSource AncestorType=TabControl}}" Value="True"/>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="CloseButton" Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
<!--卡片模式下选中的Tab也显示关闭按钮-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding (helpers:TabControlHelper.IsEditable), RelativeSource={RelativeSource AncestorType=TabControl}}" Value="True"/>
<Condition Binding="{Binding (helpers:TabControlHelper.TabType), RelativeSource={RelativeSource AncestorType=TabControl}}" Value="Card"/>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="CloseButton" Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--关闭按钮的样式-->
<Style x:Key="Antd.Button.CloseTab" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Foreground" Value="{DynamicResource AntDesign.Brush.TextSecondary}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" CornerRadius="2">
<TextBlock Text="×"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontWeight="Bold"
FontSize="14"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#80808030"/>
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
<!-- 将样式应用到项目中所有的 TabControl -->
<Style TargetType="{x:Type TabControl}" BasedOn="{StaticResource Ant.TabControl}"/>
</ResourceDictionary>