如何使用 WPF 创建平面组合框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22673483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a Flat combo box using WPF?
提问by Yoiku
Hi I want to create a flat combo box with wpf. Acctually I have already done it but when the mouse is over the combo box it returns to its old style.
嗨,我想用 wpf 创建一个平面组合框。实际上我已经完成了,但是当鼠标位于组合框上方时,它会恢复到原来的样式。
I have this xaml code:
我有这个 xaml 代码:
<Style TargetType="ComboBox" x:Key="Flat_ComboBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="MinWidth" Value="60"/>
<Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="TextElement.Foreground" Value="Black"/>
<Setter Property="FrameworkElement.FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="White" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightSkyBlue" />
</Trigger>
</Style.Triggers>
</Style>
Which properties of the Trigger "IsMouseOver" do I need to change?
我需要更改触发器“IsMouseOver”的哪些属性?
采纳答案by Chris
You'll need to override the ControlTemplatefor your ComboBox. The link that voddy mentioned in the comments will lead you (via another link) to the default ComboBoxstyle (http://msdn.microsoft.com/en-us/library/ms752094.aspx) which you should be able to tweak to get the appearance you want.
您需要ControlTemplate为您的ComboBox. 评论中提到的 voddy 链接将引导您(通过另一个链接)到默认ComboBox样式(http://msdn.microsoft.com/en-us/library/ms752094.aspx),您应该能够调整以获得你想要的外观。
As an alternative, you can try the ControlTemplateincluded with Kaxaml (a neat XAML tool), which already a more "flat" appearance.
作为替代方案,您可以尝试ControlTemplateKaxaml(一种简洁的 XAML 工具)附带的工具,它已经具有更“扁平”的外观。
For Reference (from Kaxaml):
供参考(来自 Kaxaml):
<!-- Enclosed in your resources, or a resource dictionary -->
<Window.Resources>
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="2"
Background="#C0C0C0"
BorderBrush="#404040"
BorderThickness="1" />
<Border
Grid.Column="0"
CornerRadius="2,0,0,2"
Margin="1"
Background="#FFFFFF"
BorderBrush="#404040"
BorderThickness="0,0,1,0" />
<Path
x:Name="Arrow"
Grid.Column="1"
Fill="#404040"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="#808080" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="#EEEEEE" />
<Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
<Setter Property="Foreground" Value="#888888"/>
<Setter TargetName="Arrow" Property="Fill" Value="#888888" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
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="#FFFFFF"
BorderThickness="1"
BorderBrush="#888888"/>
<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="#888888"/>
</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.Triggers>
</Style.Triggers>
</Style>
<!-- SimpleStyles: ComboBoxItem -->
<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border
Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="#DDDDDD"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Will produce something that looks like this:
将产生如下所示的内容:


You'll probably want to separate the template into a ResourceDictionary, so you can use it in multiple places.
您可能希望将模板分成一个ResourceDictionary,以便您可以在多个地方使用它。
You may also want to alter the line:
您可能还想更改该行:
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
To use a named key, which you can then apply to specific ComboBoxelements:
要使用命名键,然后您可以将其应用于特定ComboBox元素:
<Style x:Key="FlatComboBoxStyle" TargetType="{x:Type ComboBox}">
<!-- Other Code -->
<ComboBox Style="{StaticResource ResourceKey=FlatComboBoxStyle}">
回答by pr0gg3r
why so complicated? ;)
为什么这么复杂?;)
<ComboBox Style="{StaticResource {x:Static ToolBar.ComboBoxStyleKey}}"/>



