Files
ShrlAlgoToolkit/NeuWPF/NeoUI/Controls/TabControl.xaml
ShrlAlgo 955a01f564 整理
2025-08-20 12:10:35 +08:00

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