<Window x:Class="ComboBoxStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderThickness="2" BorderBrush="#e8e8e8" />
<Border Grid.Column="1" Background="#e8e8e8" Cursor="Hand"/>
<Path x:Name="Arrow" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z" Margin="16,16,10,10" Stretch="Fill" Fill="White" />
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border x:Name="bd" >
<Grid>
<!--ToggleButton 已数据绑定到 ComboBox 本身以切换 IsDropDownOpen-->
<ToggleButton Grid.Column="2" Template="{DynamicResource ComboBoxToggleButton}" x:Name="ToggleButton" Focusable="false" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
<ContentPresenter HorizontalAlignment="Left" Margin="11,3,23,3" x:Name="ContentSite" VerticalAlignment="Center" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" IsHitTestVisible="False"/>
<!--必须将 TextBox 命名为 PART_EditableTextBox,否则 ComboBox 将无法识别它-->
<TextBox Visibility="Hidden" Template="{DynamicResource ComboBoxTextBox}" HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="PART_EditableTextBox" Style="{x:Null}" VerticalAlignment="Center" Focusable="True" Background="Transparent" IsReadOnly="{TemplateBinding IsReadOnly}"/>
<!--Popup 可显示 ComboBox 中的项列表。IsOpen 已数据绑定到通过 ComboBoxToggleButton 来切换的 IsDropDownOpen-->
<Popup IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" x:Name="Popup" Focusable="False" AllowsTransparency="True" PopupAnimation="Slide">
<Grid MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{TemplateBinding ActualWidth}" x:Name="DropDown" SnapsToDevicePixels="True">
<Border x:Name="DropDownBorder" Background="{DynamicResource WindowBackgroundBrush}" BorderBrush="{DynamicResource SolidBorderBrush}" BorderThickness="1"/>
<ScrollViewer Margin="4,6,4,6" Style="{DynamicResource SimpleScrollViewer}" SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<!--StackPanel 用于显示子级,方法是将 IsItemsHost 设置为 True-->
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" Background="White"/>
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" TargetName="bd" Value="#7eb5eb" />
<Setter Property="BorderThickness" TargetName="bd" Value="2" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ComboBox Width="303" BorderBrush="#e8e8e8" VerticalContentAlignment="Center" Margin="60,78,154,201" ItemsSource="{Binding ElementName=listbox}">
<ComboBoxItem>aaa</ComboBoxItem>
<ComboBoxItem>bbb</ComboBoxItem>
<ComboBoxItem>ccc</ComboBoxItem>
<ComboBoxItem>ddd</ComboBoxItem>
</ComboBox>
<Button Content="Button" HorizontalAlignment="Left" Margin="166,209,0,0" VerticalAlignment="Top" Width="87" Click="Button_Click" Height="30"/>
</Grid>
</Window>