WPF の ComboBox は Background を設定しても、折りたたみ時の「本体」が思った色にならず戸惑いがちです。原因は、見た目が既定の ControlTemplate 内で決め打ちされているため。この記事では外部ライブラリも巨大なテーマ辞書も使わず、手元の XAML だけで「本体」「ドロップダウン両方」を好みの色に変える、最小手順と実用テンプレートをまとめて解説します。
問題の本質と設計の前提
WPF のコントロールは「プロパティ」そのものと「テンプレート」によって外観が分離されています。ComboBox.Background に色を入れても、テンプレート側で独自のブラシが使われていれば本体は変わりません。特に ComboBox は以下の複合構造になっています。
- 本体(折りたたみ時の表示面)= ToggleButton + ContentPresenter
- ドロップダウン(クリック後に開く部分)= Popup + ItemsPresenter(ScrollViewer 内)
既定テンプレートは本体の Border に固定のブラシを持っていることが多く、ここを書き換えない限り Background は通りません。したがって「テンプレートのコピー&編集」が最短解です。
| 領域 | 既定テンプレートの要素 | 反映されやすいプロパティ | 注意点 |
|---|---|---|---|
| 本体(折りたたみ) | Border(ToggleButton 内) | BorderBrush / BorderThickness | Background はテンプレート内の固定ブラシが優先されがち |
| ドロップダウン | Popup 内 Border + ItemsPresenter | Background / Padding | 開閉アニメや影を持つ場合あり。背景は別 Border に定義される |
| 編集可能時(IsEditable=True) | PART_EditableTextBox | TextBox の Background / Foreground | TextBox が透明で本体色が透ける構造だと設定場所を誤りやすい |
最短の結論:テンプレートを「コピーして編集」する
- Visual Studio(または Blend)で対象の
ComboBoxを右クリック → テンプレートの編集 ▶ コピーを編集。 - 生成された
Style(例:ComboBoxStyle1)内のControlTemplateを開き、本体側のBorderと Popup 側のBorderのBackgroundを好きな色に変更。 - その
Styleを対象のComboBoxにStyle="{StaticResource ...}"で適用。
以降では、コピー後にどこをどう変えればよいかが一目で分かる 最小テンプレート例 と 編集可能(IsEditable=True)対応版 を提示します。どちらも外部辞書不要、単一 XAML で完結します。
色リソースをひとまとめにする(任意/再利用に便利)
まずは色を変えたい箇所をまとめて管理できるように、色ブラシを数個だけ用意しておくと、後から色替えが楽です。
<Window.Resources>
<SolidColorBrush x:Key="ComboBaseBrush" Color="#FFEAF4FF"/>
<SolidColorBrush x:Key="ComboMouseOverBrush" Color="#FFD6ECFF"/>
<SolidColorBrush x:Key="ComboPressedBrush" Color="#FFC6E4FF"/>
<SolidColorBrush x:Key="ComboBorderBrush" Color="#FF5BA3E0"/>
<SolidColorBrush x:Key="ComboPopupBrush" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboDisabledBrush" Color="#FFF0F0F0"/>
</Window.Resources>
以降のテンプレートではこれらのキーを参照します。もちろん固定色(例:LightSkyBlue)に直書きしても構いません。
実装例(非編集型):本体色も Popup もまとめて変える最小テンプレート
最も需要が多い「折りたたみ時の面の色を変えたい」を満たすシンプルなテンプレートです。ポイントは テンプレート内の最上位 Border(x:Name=”MainBorder”) の Background を差し替えること。さらに IsMouseOver・IsPressed で色を切り替えるトリガも付けています。
<Style x:Key="ComboBox.SolidBackground" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="{StaticResource ComboBaseBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Border x:Name="MainBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2" />
<Grid Margin="0">
<ContentPresenter x:Name="ContentSite"
Margin="6,2,24,2"
VerticalAlignment="Center"
HorizontalAlignment="Left"
RecognizesAccessKey="True"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
IsHitTestVisible="False" />
<ToggleButton x:Name="DropDownToggle"
Width="20"
HorizontalAlignment="Right"
Focusable="False"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Background="Transparent"
BorderThickness="0">
<Grid>
<Path Margin="0,0,0,0"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z" />
</Grid>
</ToggleButton>
</Grid>
<Popup x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Border x:Name="PopupBorder"
Background="{StaticResource ComboPopupBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboMouseOverBrush}" />
</Trigger>
<Trigger SourceName="DropDownToggle" Property="IsPressed" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboPressedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboDisabledBrush}" />
<Setter Property="Foreground" Value="#FF888888"/>
</Trigger>
<Trigger Property="HasItems" Value="False">
<Setter TargetName="PopupBorder" Property="MinHeight" Value="22"/>
</Trigger>
<Trigger Property="IsEditable" Value="True">
<Setter Property="IsTabStop" Value="False"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
適用例:
<ComboBox Width="140" Height="26"
Style="{StaticResource ComboBox.SolidBackground}">
<ComboBoxItem Content="C:\" />
<ComboBoxItem Content="D:\" />
<ComboBoxItem Content="E:\" />
</ComboBox>
ここがポイント
Background="{TemplateBinding Background}"にしてあるので、ComboBox側のBackgroundを変えれば本体面も即座に変わります。色を固定したい場合はここに直接色を書いて構いません。- ドロップダウンの背景は
PopupBorderのBackgroundで制御しています。ここも固定色にすれば、ポップアップ側だけ別色にできます。
実装例(編集可能):IsEditable=True の TextBox も同色に
IsEditable="True" のときは内部に PART_EditableTextBox が出現します。これをテンプレートに用意し、背景や枠線を本体と合わせます。選択ボックス表示(非編集)と切り替えるために、編集用テキストボックスを前面に置き IsEditable のトリガで可視状態を切替えます。
<Style x:Key="ComboBox.Editable.SolidBackground" TargetType="{x:Type ComboBox}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="{StaticResource ComboBaseBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Border x:Name="MainBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2" />
<Grid>
<TextBox x:Name="PART_EditableTextBox"
Margin="6,2,24,2"
Background="Transparent"
BorderThickness="0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Focusable="True"
Visibility="Collapsed">
<ScrollViewer x:Name="PART_ContentHost"/>
</TextBox>
<ContentPresenter x:Name="ContentSite"
Margin="6,2,24,2"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="False"/>
<ToggleButton x:Name="DropDownToggle"
Width="20"
HorizontalAlignment="Right"
Focusable="False"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Background="Transparent"
BorderThickness="0">
<Grid>
<Path Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z" />
</Grid>
</ToggleButton>
</Grid>
<Popup x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Border Background="{StaticResource ComboPopupBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEditable" Value="True">
<Setter TargetName="ContentSite" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="PART_EditableTextBox" Property="Background"
Value="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter TargetName="PART_EditableTextBox" Property="Foreground"
Value="{TemplateBinding Foreground}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboMouseOverBrush}" />
</Trigger>
<Trigger SourceName="DropDownToggle" Property="IsPressed" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboPressedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboDisabledBrush}" />
<Setter Property="Foreground" Value="#FF888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
適用例:
<ComboBox Width="180" Height="26" IsEditable="True"
Style="{StaticResource ComboBox.Editable.SolidBackground}">
<sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib">C:\</sys:String>
<sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib">D:\</sys:String>
</ComboBox>
「最小編集だけで済ませたい」ためのコツ
- コピーしたテンプレートのうち、本体側の最上位
BorderのBackgroundだけ変更する。余計な編集を避ければ将来のメンテ負荷が下がります。 - 色は
TemplateBinding Backgroundにしておき、個別のComboBoxにBackground="LightSkyBlue"などを与える運用にするとテンプレートの再配布が不要。 IsEditable=Trueを混在させる画面では、非編集用と編集用でStyleを分けると混乱しません。
ドロップダウン(Popup)側の色と枠をそろえる
ドロップダウンの背景を本体と同じにしたい場合は Popup 内の Border にも同じブラシを適用します。
<Border x:Name="PopupBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</Border>
一方で「本体はブルー、リストは白」のように分けたいなら、PopupBorder.Background に固定色(または別ブラシキー)を指定してください。
選択項目のハイライト(ItemContainerStyle)
テンプレートとは別に、ComboBoxItem の見た目は ItemContainerStyle で制御できます。背景カラー設計を統一したい場合は、選択状態(IsSelected=True)やマウスオーバー時の色をここでそろえます。
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Padding" Value="8,4"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFEAF4FF"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFD6ECFF"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FF999999"/>
</Trigger>
</Style.Triggers>
</Style>
Accessibility とコントラストの配慮
- 背景色を明るくしたら、
Foregroundを十分なコントラストになるように調整しましょう(推奨 4.5:1 以上)。 - 無効状態(
IsEnabled=False)ではOpacityを落とすだけでなく文字色も薄くして、視認性を確保します。 - キーボード操作派へは
KeyboardNavigation.TabNavigationの挙動確認を。トグルボタンがフォーカスを奪わないよう、テンプレート内のToggleButtonはFocusable="False"に。
アプリ全体に一括適用したい場合
ページ(Window/UserControl)単位ではなく全画面で統一したいなら、App.xaml の Application.Resources に TargetType="ComboBox" のスタイルをキーなしで置きます。キーを外すと「暗黙スタイル」としてすべての ComboBox に適用されます。
<Application.Resources>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource ComboBox.SolidBackground}"/>
</Application.Resources>
注意: 既に一部で別スタイルを使っている場合は、影響範囲を確認してから段階的に移行しましょう。暗黙スタイルは強力ですが、意図せず広範囲の外観が変わることがあります。
動的テーマ切替(ライト/ダーク)への備え
将来の色切替を見据えるなら、色はすべてブラシキー経由で参照し、DynamicResource を使います。以下はベース色のみ切り替える例です。
<Window.Resources>
<SolidColorBrush x:Key="ComboBaseBrush" Color="#FFEAF4FF"/>
<!-- 略 -->
</Window.Resources>
<!-- ボタンなどでテーマを切替 -->
<Button Content="ダークにする" Click="OnSwitchTheme"/>
コードビハインドでは Resources["ComboBaseBrush"] の Color を上書きするか、別の ResourceDictionary をマージしてください。テンプレート側は {DynamicResource ComboBaseBrush} にしておくと即時反映されます。
動作確認チェックリスト
| 確認項目 | 期待する挙動 |
|---|---|
| 折りたたみ時の本体色 | Background の設定色が表示される |
| マウスオーバー/押下 | トリガに応じて色が切替わる(にじみ・破綻なし) |
| ドロップダウン背景 | Popup 内 Border の色が反映される |
| 編集可能モード | PART_EditableTextBox の背景が本体と整合 |
| 無効状態 | 背景・文字色ともに視認性を保ちつつ無効感が出ている |
| 高 DPI/スケーリング | アイコン(▼)や枠が滲まず、余白が過不足ない |
トラブルシューティング
- 「背景が変わらない」:テンプレート内の
Borderではなく、別のパネルや装飾に色が乗っている可能性。コピーしたテンプレートでx:Nameを検索し、一番外側の塗りつぶし要素を特定してください。 - 「選択文字が読みづらい」:背景を明るくしたのに
Foregroundを黒のままにしていませんか。ItemContainerStyleのIsSelectedトリガで明度差を確保。 - 「IsEditable=True で色がズレる」:TextBox 側の
BackgroundがTransparentのままだと下地の色が透け、フォーカス時のシステム色が勝つことがあります。上記テンプレートのようにPART_EditableTextBoxに明示的に背景を渡してください。 - 「枠線の色だけ変えたい」:
BorderBrushをテンプレートで{TemplateBinding BorderBrush}に。個別のコントロールにBorderBrush=...を設定すれば反映されます。 - 「大量の XAML が増えて保守が不安」:最小箇所(本体の
Border)だけ編集して、他は既定のままに。色はブラシキー化してコード量を抑えます。
運用テクニック(現場ノウハウ)
- 「画面デザイナーで差分を作る」:まずは VS/Blend の「コピーを編集」でフルテンプレートを生成し、不要箇所を少しずつ削って 最小構成 に寄せると安全です。
- 「キー付きスタイルで段階導入」:既存画面を壊さないため、最初は
x:Key付きスタイルで特定画面だけ適用 → 問題なければ暗黙スタイル化がセオリー。 - 「フォーカス可視化」:キーボード操作向けには
FocusVisualStyleで枠の太さや色を調整すると UX が向上します。
サンプル:1 ファイルで完結するデモ Window
以下を丸ごと貼り付ければ、この記事のポイントが試せます(必要に応じて xmlns は調整してください)。
<Window x:Class="ComboDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Combo Demo" Height="320" Width="420">
<Window.Resources>
<SolidColorBrush x:Key="ComboBaseBrush" Color="#FFEAF4FF"/>
<SolidColorBrush x:Key="ComboMouseOverBrush" Color="#FFD6ECFF"/>
<SolidColorBrush x:Key="ComboPressedBrush" Color="#FFC6E4FF"/>
<SolidColorBrush x:Key="ComboBorderBrush" Color="#FF5BA3E0"/>
<SolidColorBrush x:Key="ComboPopupBrush" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboDisabledBrush" Color="#FFF0F0F0"/>
<!-- 非編集用スタイル(本文で解説したもの) -->
<Style x:Key="ComboBox.SolidBackground" TargetType="{x:Type ComboBox}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="{StaticResource ComboBaseBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Border x:Name="MainBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2"/>
<Grid>
<ContentPresenter x:Name="ContentSite"
Margin="6,2,24,2"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="False"/>
<ToggleButton x:Name="DropDownToggle"
Width="20"
HorizontalAlignment="Right"
Focusable="False"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Background="Transparent"
BorderThickness="0">
<Grid>
<Path Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
</ToggleButton>
</Grid>
<Popup x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Border Background="{StaticResource ComboPopupBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboMouseOverBrush}"/>
</Trigger>
<Trigger SourceName="DropDownToggle" Property="IsPressed" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboPressedBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboDisabledBrush}"/>
<Setter Property="Foreground" Value="#FF888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- 編集可能用スタイル(本文で解説したもの) -->
<Style x:Key="ComboBox.Editable.SolidBackground" TargetType="{x:Type ComboBox}"
BasedOn="{StaticResource ComboBox.SolidBackground}">
<Setter Property="IsEditable" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Border x:Name="MainBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2"/>
<Grid>
<TextBox x:Name="PART_EditableTextBox"
Margin="6,2,24,2"
Background="Transparent"
BorderThickness="0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Visibility="Collapsed">
<ScrollViewer x:Name="PART_ContentHost"/>
</TextBox>
<ContentPresenter x:Name="ContentSite"
Margin="6,2,24,2"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Content="{TemplateBinding SelectionBoxItem}"
IsHitTestVisible="False"/>
<ToggleButton x:Name="DropDownToggle"
Width="20" HorizontalAlignment="Right"
Focusable="False"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press" Background="Transparent" BorderThickness="0">
<Grid><Path Stretch="Uniform" Data="M 0 0 L 4 4 L 8 0 Z"/></Grid>
</ToggleButton>
</Grid>
<Popup x:Name="Popup" Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True" Focusable="False"
PopupAnimation="Slide">
<Border Background="{StaticResource ComboPopupBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEditable" Value="True">
<Setter TargetName="ContentSite" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="PART_EditableTextBox" Property="Background"
Value="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboMouseOverBrush}"/>
</Trigger>
<Trigger SourceName="DropDownToggle" Property="IsPressed" Value="True">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboPressedBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="MainBorder" Property="Background"
Value="{StaticResource ComboDisabledBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Padding" Value="8,4"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFEAF4FF"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFD6ECFF"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="12"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="12"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="非編集 ComboBox" FontWeight="Bold"/>
<ComboBox Grid.Row="2" Width="180" Height="26"
Style="{StaticResource ComboBox.SolidBackground}">
<ComboBoxItem Content="C:\"/>
<ComboBoxItem Content="D:\"/>
<ComboBoxItem Content="E:\"/>
</ComboBox>
<TextBlock Grid.Row="4" Text="編集可能 ComboBox" FontWeight="Bold"/>
<ComboBox Grid.Row="4" Margin="160,0,0,0" Width="200" Height="26"
IsEditable="True"
Style="{StaticResource ComboBox.Editable.SolidBackground}">
<sys:String>C:\</sys:String>
<sys:String>D:\</sys:String>
<sys:String>E:\</sys:String>
</ComboBox>
</Grid>
</Window>
なぜ Background だけでは変わらなかったのか(理解を定着)
理由はシンプルで、テンプレートが最終決定権を持つからです。TemplateBinding で Background を参照していれば ComboBox.Background は反映されますが、既定テンプレートが独自ブラシを持っていたり、VisualState/トリガで別ブラシに入れ替えていれば、プロパティ側の値は「見た目」に届きません。したがって、本記事のように「テンプレートのコピー&編集」で本体の Border を自分の管理下に置くのが唯一確実な方法になります。
メリット・デメリットの整理
| 観点 | メリット | デメリット |
|---|---|---|
| 外部依存 | 外部ライブラリ不要。単一 XAML に収まる | 既定テンプレートの変更点を自前で追従する必要 |
| カスタマイズ範囲 | 本体・Popup・フォーカス・無効時まで一括制御 | テンプレートを理解する初期コストが少しある |
| 保守性 | ブラシキー化で配色差し替えが容易 | フルテンプレートのコピペは行数が増える |
まとめ
ComboBox の色を「本体ごと」変えるには、既定テンプレートをコピーして本体の Border の Background を書き換えるのが確実です。最小構成テンプレートなら外部辞書も不要で、XAML ファイルだけで完結できます。
さらに、Popup 側・ComboBoxItem・IsEditable=True の PART_EditableTextBox まで含めて色をそろえれば、画面全体の統一感と可読性が向上します。運用では色をブラシキーに集約し、段階導入(キー付きスタイル→暗黙スタイル)で適用範囲を広げるのがおすすめです。

コメント