WPF 標準コントロールデモアプリ › ComboBox
ComboBox Inputs
ComboBox はリストからアイテムを選択できるドロップダウンリストコントロールです。IsEditable を有効にするとテキスト入力も可能になります。シンプルなアイテムリストからデータバインドされた複雑なコレクションまで対応しています。
概要
WPF の ComboBox は、ドロップダウンリストから1つの項目を選択するためのコントロールです。
Selector → ItemsControl という継承チェーンにより、
ItemsSource へのデータバインドや ItemTemplate による表示カスタマイズが可能です。
IsEditable="True" に設定すると、ドロップダウンの選択だけでなく任意テキストの入力も可能になります。
これにより、候補リストを参考にしながらも自由な値を入力できる UI を実現できます。
StaysOpenOnEdit と組み合わせると、入力中もドロップダウンを表示し続けられます。
SelectedValue / SelectedValuePath の組み合わせは、
オブジェクトコレクションから特定のプロパティ値(ID など)を取得する際に便利です。
例えば、SelectedValuePath="Id" と設定すると、選択されたオブジェクトの Id プロパティ値を
SelectedValue で取得できます。
DisplayMemberPath を設定すると、ItemTemplate を定義しなくても
コレクション内のオブジェクトの特定プロパティをドロップダウンに表示できます。
複雑な表示が不要なシナリオではこれが最も簡潔なアプローチです。
画面キャプチャ
デモしているプロパティ
以下のプロパティが WPF 標準コントロールデモアプリでインタラクティブにデモされています。
| プロパティ | 設定値 | 説明 |
|---|---|---|
IsDropDownOpen |
bool |
ドロップダウンリストの開閉をプログラムから制御したい場合や、バインドで現在の開閉状態を追跡したい場合に使用します。True にするとドロップダウンが開き、False にすると閉じます。デフォルトは False です。はまりポイント: このプロパティを TwoWay バインドすると、ユーザーがドロップダウンを閉じた直後に ViewModel 側の値が False に更新され、さらにそれが True に変更されると即座に再オープンしてしまいます。バインド変更のタイミングに十分注意してください。 |
IsEditable |
bool |
リストの選択肢に限らずユーザーが自由な値を入力できるようにしたい場合(オートコンプリート、フリー入力型ドロップダウンなど)に True に設定します。True にすると Text プロパティがアクティブになり、ユーザーが入力したテキストを取得・バインドできます。はまりポイント: IsEditable=True のとき、ユーザーがリストにない値を入力すると SelectedItem は null になります。SelectedItem だけを参照する ViewModel の実装では、フリー入力値が失われる場合があるため Text プロパティも合わせて参照してください。 |
IsReadOnly |
bool |
IsEditable=True の状態で、テキスト入力は禁止しつつドロップダウンからの選択は許可したい場合に使用します。IsEditable=True かつ IsReadOnly=True に設定すると、テキスト部分は読み取り専用(直接入力不可)になりますが、ドロップダウンを開いてリストから選択する操作は引き続き可能です。IsEditable=False(デフォルト)の場合はこのプロパティは効果がありません。はまりポイント: IsReadOnly 単体でドロップダウン全体を無効化することはできません。コントロール全体を無効化したい場合は IsEnabled=False を使ってください。 |
MaxDropDownHeight |
double |
アイテム数が多い場合にドロップダウンが画面からはみ出すのを防ぎ、スクロールバーで探せるようにしたい場合に設定します。デフォルトは制限なし(double.PositiveInfinity)で、アイテム数が多いとドロップダウンが画面全体を占領することがあります。設定した高さを超えるとドロップダウン内にスクロールバーが表示されます。はまりポイント: 小さすぎる値(例: アイテム1件分以下)を設定すると、ドロップダウンを開いてもほとんど何も見えない状態になります。アイテムの高さ × 最低表示件数(5〜8件程度)を目安に設定してください。 |
Text |
string |
IsEditable=True のときに現在のテキスト値(選択アイテムの表示文字列またはユーザー入力テキスト)を取得・バインドするために使用します。選択アイテムが変わると SelectedItem.ToString() の代わりに DisplayMemberPath で指定したプロパティの値が Text に反映されます。はまりポイント: IsEditable=False(デフォルト)の状態でプログラムから Text プロパティを設定しても表示に反映されません。表示を変えたい場合は SelectedItem または SelectedIndex を設定してください。 |
StaysOpenOnEdit |
bool |
IsEditable=True のとき、入力に応じて候補リストをリアルタイムで絞り込む UI(オートコンプリート)を実現する場合に True に設定します。True にするとテキスト編集中もドロップダウンが開いたままになります。デフォルト(False)ではテキストを編集するとドロップダウンが閉じます。はまりポイント: True に設定すると、ユーザーが意図せずリストを閉じたいのに閉じられないという操作上の混乱を招くことがあります。リアルタイム候補絞り込みが必要なシナリオ以外では使用しないことを推奨します。 |
SelectedIndex (Selector) |
int |
プログラムから特定のアイテムを選択状態にしたい場合に使用します。0始まりのインデックスで選択アイテムを指定し、指定したインデックスのアイテムが選択されハイライト表示されます。-1 は未選択状態を意味し、デフォルト値でもあります。はまりポイント: SelectedIndex=-1 を設定するとインデックスによる選択がクリアされますが、SelectedItem が必ずしも null にリセットされるわけではありません。選択を完全にクリアしたい場合は SelectedItem=null と合わせて設定してください。 |
SelectedItem (Selector) |
object |
オブジェクトコレクションにバインドしている場合に、選択されたオブジェクト全体を ViewModel で受け取りたいときに使用します。Mode=TwoWay でバインドすると ViewModel から選択アイテムをプログラムで変更することもできます。はまりポイント: WPF は SelectedItem の比較に参照等価性(同じオブジェクトインスタンスかどうか)を使用します。ViewModel で別途作成したオブジェクト(例: データベースから再取得したもの)を設定しても、ItemsSource 内の参照と一致しない場合は選択状態になりません。ItemsSource と同じインスタンスを設定するか、SelectedValue + SelectedValuePath の使用を検討してください。 |
SelectedValue / SelectedValuePath / DisplayMemberPath |
object / string / string |
オブジェクトのコレクション(例: 製品リスト)から特定のプロパティ値(例: ID)だけを ViewModel にバインドしたい場合の典型的なパターンで使用します。SelectedValuePath="ProductId" と設定すると選択された製品オブジェクトの ProductId プロパティ値が SelectedValue として取得でき、DisplayMemberPath="Name" でドロップダウンに Name プロパティが表示されます。はまりポイント: SelectedValuePath の値はプロパティ名の大文字・小文字を区別します(例: "productId" と "ProductId" は別物)。一致しない場合は SelectedValue が常に null になるため、プロパティ名のスペルを必ず確認してください。 |
XAML 使用例
<!-- シンプルなデータバインド -->
<ComboBox ItemsSource="{Binding Countries}"
SelectedItem="{Binding SelectedCountry, Mode=TwoWay}"
DisplayMemberPath="Name" />
<!-- SelectedValuePath を使用した ID 取得 -->
<ComboBox ItemsSource="{Binding Products}"
DisplayMemberPath="Name"
SelectedValuePath="ProductId"
SelectedValue="{Binding SelectedProductId, Mode=TwoWay}" />
<!-- 編集可能 ComboBox -->
<ComboBox IsEditable="True" StaysOpenOnEdit="True"
MaxDropDownHeight="200"
Text="{Binding SearchText, Mode=TwoWay}"
ItemsSource="{Binding Suggestions}" />
主な使用例
- 国・地域の選択 — 固定リストから国や地域を選択する標準的なドロップダウンセレクターとして使用します。
- カテゴリ・分類の選択 — 製品カテゴリや優先度(高/中/低)など、有限の選択肢から1つを選ぶ UI に使用します。
- オートコンプリート検索 — IsEditable と StaysOpenOnEdit を組み合わせて、入力に応じて候補を絞り込む検索 UI を作成します。
- フィルター選択 — 日付範囲や状態など、表示フィルターの選択肢をドロップダウンで提供します。
- 設定値の選択 — アプリの設定画面で「テーマ」「言語」「フォントサイズ」などを選択する UI に使用します。
ヒントとベストプラクティス
- SelectedItem vs SelectedValue — オブジェクト全体が必要な場合は
SelectedItemを、特定のプロパティ値(ID など)だけ必要な場合はSelectedValue+SelectedValuePathを使います。ただしSelectedItemは参照等価性で比較されるため、同じデータを別のインスタンスとして設定しても選択状態にならない点に注意してください。 - デフォルト選択を設定する — アプリ起動時やダイアログ表示時に ViewModel から
SelectedItemまたはSelectedIndexを設定して初期値を表示します。SelectedItemを使う場合はItemsSourceのコレクションと同じオブジェクトインスタンスを参照するように注意してください。 - 空の選択を許可する場合 — コレクションの先頭に「選択してください」という
null値を追加するか、SelectedItemがnullの場合の処理を ViewModel に実装します。CompositeCollectionを使うと既存のコレクションを変更せずに先頭に固定アイテムを追加できます。 - 大量のアイテム — アイテム数が多い場合は
MaxDropDownHeightでリストの高さを制限し、スクロールで探せるようにします。数百件以上のアイテムを扱う場合は仮想化(VirtualizingStackPanel)が自動的に有効になりますが、ItemTemplateを使う場合は明示的に有効化することを確認してください。 - ItemTemplate でリッチ表示 — 単純なテキストリストではなく、アイコンや詳細情報を含む複雑なリストアイテムを表示する場合は
ItemTemplateを定義します。DisplayMemberPathはItemTemplateと併用できないため、どちらかを選択してください。 - IsEditable=True 時の SelectedItem null チェック —
IsEditable=Trueのとき、ユーザーがリスト外の値を入力するとSelectedItemはnullになります。フリー入力を許可する場合はSelectedItemとTextの両方を参照して処理を実装してください。
関連コントロール
- ListBox — スクロール可能なリストから単一または複数選択する場合に使用します。
- TextBox — 自由テキスト入力のみが必要な場合。
- RadioButton — 選択肢が少なく(3〜5個程度)、常に表示しておきたい場合に適しています。
ソースコード
このデモ画面のソースコードは GitHub で公開しています。アプリ内の「コード表示」ボタンから各プロパティの実際の XAML を確認できます。