Windows Explorer で使われているコンボボックスのイメージはこんな感じのものです。
それを、こんな感じで作ってみました。左が作ったもの。右はなにもスタイルを与えていないデフォルトです。
影表示もしないし、リストアイテムの伸びる演出もありません。ただ、色味はかなり Windows Explorer ライク。
スタイル
こんな感じで定義しました。コンボボックスの見た目の基本が ToggleButton
のようになっていますが、これはデフォルトの ComboBox
のスタイルがそのようになっています。「Microsoft Docs - ComboBox のスタイルとテンプレート」を確認してみるとよいと思います。
<ControlTemplate x:Key="SlimComboBoxButtonTemplate" TargetType="{x:Type ToggleButton}"> <Border x:Name="Border" BorderThickness="1" BorderBrush="Transparent" Background="Transparent"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Path x:Name="Arrow" Grid.Column="1" Margin="4 0 4 0" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" Data="M 0 0.5 L 3 3.5 L 6 0.5 Z" Fill="#212121" /> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="Border" Property="BorderBrush" Value="#DD99CCFF"/> <Setter TargetName="Border" Property="Background" Value="#2299CCFF"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="Border" Property="BorderBrush" Value="#EE99CCFF"/> <Setter TargetName="Border" Property="Background" Value="#4499CCFF"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <Style x:Key="SlimComboBoxItemStyle" 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" Margin="0 1 0 0" BorderThickness="1" BorderBrush="Transparent" SnapsToDevicePixels="true"> <ContentPresenter /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsHighlighted" Value="true"> <Setter TargetName="Border" Property="BorderBrush" Value="#DD99CCFF"/> <Setter TargetName="Border" Property="Background" Value="#2299CCFF"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="#4499CCFF"/> </Trigger> <Trigger Property="IsSelected" Value="true"> <Setter TargetName="Border" Property="BorderBrush" Value="#DD99CCFF"/> <Setter TargetName="Border" Property="Background" Value="#2299CCFF"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="SlimComboBoxStyle" 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="ItemContainerStyle" Value="{StaticResource SlimComboBoxItemStyle}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ComboBox}"> <Grid> <ToggleButton x:Name="ToggleButton" Template="{StaticResource SlimComboBoxButtonTemplate}" ClickMode="Press" Focusable="false" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" /> <ContentPresenter x:Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3 3 23 3" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> <TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Margin="3 3 23 3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" > <TextBox.Template> <ControlTemplate TargetType="TextBox" > <Border Name="PART_ContentHost" Focusable="False" /> </ControlTemplate> </TextBox.Template> </TextBox> <Popup Name="Popup" AllowsTransparency="True" Focusable="False" PopupAnimation="None" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}"> <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}"> <Border x:Name="DropDownBorder" Background="White" BorderThickness="1" BorderBrush="#CCCCCC"/> <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="IsGrouping" Value="true"> <Setter Property="ScrollViewer.CanContentScroll" Value="false" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
使う例
スタイルに指定しただけです。
<ComboBox Width="100" Style="{DynamicResource SlimComboBoxStyle}" SelectedIndex="0"> <ComboBoxItem>ランス</ComboBoxItem> <ComboBoxItem>シィル</ComboBoxItem> <ComboBoxItem>あてな2号</ComboBoxItem> <ComboBoxItem>魔想志津香</ComboBoxItem> <ComboBoxItem>上杉謙信</ComboBoxItem> <ComboBoxItem>山本五十六</ComboBoxItem> </ComboBox>
変更点
通常の ComboBox
コントロールは、アニメーションがたくさん用意されていますが、それらを省きました。ポップアップの表示なんかも、応答が機敏になっていると思います。
また、画像を見ればわかるとおり、縦に連続するコンボボックスはごちゃつきます。シンプルな見た目にしてあげたほうが、よい場合もあります。
太さが細めなのは、いつもどおり Padding でいいです。雛形。
サンプル
GitHub の「Samples」リポジトリーにまとめて公開しています。今回のサンプルは「SimpleComboBoxSample」です。
参考
C#WPFの道【XAMLに慣れる編】: WindowsFormsプログラマーがWPFを書く方法
- 作者:ピーコックアンダーソン
- 発売日: 2019/02/04
- メディア: Kindle版