Files
ShrlAlgoToolkit/AntDesignWPF/Controls/TabControl.xaml
2025-07-31 20:12:24 +08:00

311 lines
20 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>