Files
Shrlalgo.RvKits/Melskin/Controls/Cascader.xaml
2026-02-20 15:31:44 +08:00

283 lines
18 KiB
XML

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:assists="clr-namespace:Melskin.Assists"
xmlns:controls="clr-namespace:Melskin.Controls"
xmlns:converters="clr-namespace:Melskin.Converters"
xmlns:internal="clr-namespace:Melskin.Converters.Internal">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Melskin;component/Themes/Animations.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="DefaultCascaderPanelStyle" TargetType="ListBox">
<!--<Setter Property="ItemContainerStyle" Value="{DynamicResource DefaultCascaderListBoxItemStyle}" />-->
<Setter Property="Background" Value="{DynamicResource BackgroundFloatingBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderNormalBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="10,4" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!-- <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" /> -->
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="AlternationCount" Value="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- 核心修正:使用 TextBlock 并通过 MultiBinding 设置 Text -->
<TextBlock Grid.Column="0" VerticalAlignment="Center">
<TextBlock.Text>
<MultiBinding Converter="{x:Static internal:PropertyValueConverter.Instance}">
<!-- 第一个绑定:当前的数据项 -->
<Binding Path="." />
<!-- 第二个绑定:从祖先 Cascader 获取 DisplayMemberPath -->
<Binding Path="DisplayMemberPath" RelativeSource="{RelativeSource AncestorType=controls:Cascader}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<controls:IconElement
x:Name="Arrow"
Grid.Column="1"
Width="8"
Height="8"
Foreground="{DynamicResource TextPrimaryBrush}"
Symbol="KeyboardArrowRight"
Visibility="Hidden" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{x:Static internal:HasChildrenMultiConverter.Instance}">
<Binding Path="." />
<Binding Path="SubmenuMemberPath" RelativeSource="{RelativeSource AncestorType=controls:Cascader}" />
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="Arrow" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border
x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4"
SnapsToDevicePixels="true">
<ScrollViewer Focusable="false">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource ControlBackgroundDisabledBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type controls:Cascader}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="{DynamicResource ControlBackgroundNormalBrush}" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="Padding" Value="10,6" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="assists:InputAssist.Clearable" Value="True" />
<Setter Property="assists:InputAssist.PlaceholderText" Value="请选择..." />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="PanelStyle" Value="{StaticResource DefaultCascaderPanelStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:Cascader}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<ToggleButton
x:Name="PART_ToggleButton"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
IsChecked="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Style="{DynamicResource ComboBoxToggleButton}" />
<TextBlock
Margin="{TemplateBinding Padding}"
VerticalAlignment="Center"
IsHitTestVisible="False"
Text="{Binding SelectedText, RelativeSource={RelativeSource AncestorType=controls:Cascader}}"
TextTrimming="CharacterEllipsis" />
<TextBlock
x:Name="Placeholder"
Margin="{TemplateBinding Padding}"
Padding="3"
VerticalAlignment="Center"
Foreground="{DynamicResource TextPlaceholderBrush}"
IsHitTestVisible="False"
Text="{Binding Path=(assists:InputAssist.PlaceholderText), RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=controls:Cascader}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedText, RelativeSource={RelativeSource AncestorType=controls:Cascader}}" Value="">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Popup
x:Name="PART_Popup"
Margin="-8"
assists:BehaviorAssist.SimulateNativeBehavior="True"
AllowsTransparency="True"
IsOpen="{Binding IsChecked, ElementName=PART_ToggleButton}"
Placement="Bottom"
PlacementTarget="{Binding ElementName=PART_ToggleButton}"
PopupAnimation="Slide"
StaysOpen="True">
<Border
x:Name="PART_Border"
MinWidth="{Binding ActualWidth, ElementName=templateRoot}"
MaxHeight="300"
Margin="8"
Background="{DynamicResource BackgroundFloatingBrush}"
BorderBrush="{DynamicResource BorderNormalBrush}"
BorderThickness="1"
CornerRadius="4"
Effect="{DynamicResource PopupShadow}"
SnapsToDevicePixels="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox
x:Name="PART_SearchBox"
Grid.Row="0"
Margin="4"
Text="{Binding SearchText, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}">
<assists:InputAssist.Suffix>
<controls:IconElement
Width="16"
Height="16"
Margin="4,2,2,0"
Foreground="{DynamicResource TextSecondaryBrush}"
Symbol="Search" />
</assists:InputAssist.Suffix>
</TextBox>
<Grid Grid.Row="1">
<ScrollViewer
x:Name="PART_CascadingView"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<ContentPresenter Content="{TemplateBinding CascadingPanel}" />
</ScrollViewer>
<!-- 改造搜索结果列表 -->
<ListBox
x:Name="PART_SearchResultsView"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding FilteredItemsSource, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Visibility="Collapsed">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- 使用一个完全透明的按钮来承载内容和命令 -->
<Button
Padding="4,2"
HorizontalContentAlignment="Stretch"
Command="{Binding RelativeSource={RelativeSource AncestorType=controls:Cascader}, Path=SelectSearchResultCommand}"
CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
x:Name="Bd"
Padding="{TemplateBinding Padding}"
Background="Transparent">
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource ControlBackgroundHoverBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<!-- 按钮的内容就是之前定义的文本 -->
<TextBlock
Text="{Binding DisplayText}"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding DisplayText}" />
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ControlBackgroundHoverBrush}" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryFocusedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource ControlBackgroundDisabledBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextDisabledBrush}" />
</Trigger>
<Trigger Property="IsDropDownOpen" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryNormalBrush}" />
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=SearchText, RelativeSource={RelativeSource Self}, Converter={x:Static converters:NullOrEmptyConverter.NotInstance}}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="PART_CascadingView" Property="Visibility" Value="Collapsed" />
<Setter TargetName="PART_SearchResultsView" Property="Visibility" Value="Visible" />
</MultiDataTrigger>
<Trigger Property="IsSearchable" Value="False">
<Setter TargetName="PART_SearchBox" Property="Visibility" Value="Collapsed" />
<Setter TargetName="PART_Border" Property="Background" Value="Transparent" />
<Setter TargetName="PART_Border" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>