c# - 附加图像上的 WPF XAML 自定义组合框样式
问题描述
我在一个现有的 WPF 应用程序中看到了一个组合框,并想在我自己的应用程序中创建类似的组合框。我将提供我想要的屏幕截图和我现在拥有的屏幕截图的代码。在第一张图片上,当它处于常规状态时有一个组合框,而在第二张图片上,当弹出窗口打开时
有一些时刻我无法实现。首先是当弹出窗口打开时 - 它与切换按钮重叠。其次是popup周围的阴影。
我当前的 XAML 样式很大,我希望有人能通过它,他会建议我如何编辑它以实现我想要的样式:
<ControlTemplate x:Key="ToggleButtonStyle" TargetType="ToggleButton" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border x:Name="OutsideBorder" Grid.ColumnSpan="2" BorderThickness="0 0 0 3" Panel.ZIndex="2"
Width="0" BorderBrush="{StaticResource PrimaryColorBrush}">
</Border>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="0"
Background="Transparent"
BorderBrush="#111111"
BorderThickness="0 0 0 1" >
</Border>
<Path
x:Name="Arrow"
Margin="0 0 4 0"
Grid.Column="1"
Fill="#757575"
Width="10" Height="6"
Stretch="Fill"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M7 10l5 5 5-5z">
</Path>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="Container" AccelerationRatio="0.4" DecelerationRatio="0.4">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OutsideBorder" Storyboard.TargetProperty="(Border.Width)">
<SplineDoubleKeyFrame KeyTime="00:00:0.15" Value="400"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard AccelerationRatio="0.4" DecelerationRatio="0.4">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OutsideBorder" Storyboard.TargetProperty="(Border.Width)">
<SplineDoubleKeyFrame KeyTime="00:00:0.1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="Container" AccelerationRatio="0.4" DecelerationRatio="0.4">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow" Storyboard.TargetProperty="Fill.Color">
<SplineColorKeyFrame KeyTime="00:00:0.13" Value="{StaticResource PrimaryColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard AccelerationRatio="0.4" DecelerationRatio="0.4">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Arrow" Storyboard.TargetProperty="Fill.Color">
<SplineColorKeyFrame KeyTime="00:00:0.13" Value="#757575"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ComboBoxEx" TargetType="ComboBox">
<Setter Property="IsEditable" Value="False"/>
<Setter Property="IsTextSearchEnabled" Value="False"/>
<Setter Property="MaxDropDownHeight" Value="300"/>
<Setter Property="IsSynchronizedWithCurrentItem" Value="True" />
<Setter Property="StaysOpenOnEdit" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Foreground" Value="#757575"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ToggleButtonStyle}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,3,23,3"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
Background="Green"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SelectDocTemplateStyle" TargetType="ComboBox" BasedOn="{StaticResource ComboBoxEx}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ToggleButtonStyle}"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="6,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<!-- Text box is not used here -->
<TextBox x:Name="PART_EditableTextBox"
HorizontalAlignment="Left"
FlowDirection="LeftToRight"
VerticalAlignment="Center"
Margin="6,3,23,3"
Focusable="True"
Foreground="Purple"
CaretBrush="Aqua"
FontSize="14"
Padding="2"
FontFamily="{StaticResource LatoBoldItalic}"
BorderThickness="0"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"
Width="{TemplateBinding Width}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
Background="#9E9E9E">
</Border>
<ScrollViewer Margin="0,0" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Local" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,0,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type ComboBoxItem}" x:Name="ComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Foreground" Value="#111111"/>
<Setter Property="FontFamily" Value="{StaticResource LatoRegular}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="FlowDirection" Value="LeftToRight"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border"
Padding="10"
Background="#E0E0E0"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="#BDBDBD"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
<Border x:Name="PART_ContentHost" Focusable="False" Background="Red" Width="{TemplateBinding Width}" />
</ControlTemplate>
所以,我的组合框现在看起来像这样,它与我想要的相去甚远:
常规状态
弹出窗口打开
主要问题是:
- 如何在弹出窗口周围创建阴影?
- 如何制作一个覆盖在切换按钮上的弹出窗口?
解决方案
WPF 开发人员有一些闭源和一些开源的 MaterialDesign 库。
感谢#ButchersBoy,您可以下载甚至修改整个主题:
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit
您需要解决并阅读类似的代码以了解您需要了解的内容。
推荐阅读
- c++ - 使用指针更改代码以实现多对多关系
- botframework - 如何获取安装 Teams bot 的团队 ID
- selenium - 使用会话快照的 Codeception 验收测试问题
- arduino - 如何在 Arduino BLE 设备上获取广告数据包的值
- sql - JPA EntityGraph 使用子图制作笛卡尔积
- c# - 使用 Linq 和 Regex 比较 2 个字符串数组以进行部分匹配
- sql-server - SQL 中的 STUFF(... FOR XML) 函数有没有办法防止重复值?
- string - 如何将单词列表读入包含单词位置的元组?
- flutter - 错误:参数类型“列表”
'不能分配给参数类型'String' - kotlin - 从普通列表构建链接列表