如何使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:21:48  来源:igfitidea点击:

How do I create a Flat combo box using WPF?

c#wpfcomboboxflat

提问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:

将产生如下所示的内容:

enter image description here

在此处输入图片说明

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}}"/>

enter image description here

在此处输入图片说明