かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その33 「ComboBoxコントロール」

ComboBoxコントロールは、複数の選択肢の中から1つをユーザーに選択してもらうためのユーザーインターフェースを提供するコントロールです。オプションとして、複数の選択肢の中から1つを選ぶか、自由にテキストを入力する方法も提供することができます。

ComboBoxの基本的な使い方は、ItemsSourceプロパティにオブジェクトのコレクションを設定して、ItemTemplateで見た目を定義する方法になります。例として、以下のようなNameとAgeプロパティを持つPersonクラスを表示する場合のコードを示します。

// ComboBoxに表示するオブジェクト
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

ComboBoxのXAMLでの定義は以下のようになります。ItemTemplateに、Personクラスの表示を定義するテンプレートを設定しています。

<ComboBox x:Name="comboBox">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Margin="2.5"/>
                <TextBlock Text="{Binding Age}" Margin="2.5"/>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

コードビハインドのコンストラクタで、このComboBoxコントロールのItemsSourceプロパティにデータを設定します。

var items = Enumerable.Range(1, 10)
    .Select(i => new Person { Name = "おおた" + i, Age = 20 + i })
    .ToList();

this.comboBox.ItemsSource = items;

この状態で実行すると、以下のようにItemTemplateに設定した見た目の通り「名前 年齢」の順番でデータが並んだ状態で表示されます。

f:id:okazuki:20140814200814p:plain

また、IsEditableプロパティをtrueに設定することで、選択肢にない項目をTextBoxと同じ要領で入力できるようにもなります。選択した項目の表示場所がTextBoxになることで、ItemTemplateの表示ができなくなるため、TextSearch.TextPathプロパティで選択した項目の、どのプロパティの値を表示するのか指定する必要があります。(省略した場合は、ToStringの結果がそのまま表示されます)

<ComboBox x:Name="comboBoxEditable" Grid.Column="2" Grid.Row="2" MinWidth="150" 
          IsEditable="True" TextSearch.TextPath="Name">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Margin="2.5"/>
                <TextBlock Text="{Binding Age}" Margin="2.5"/>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

f:id:okazuki:20140814200852p:plain

選択項目の操作

ComboBoxコントロールで選択された要素を取得するには、インデックスを取得する方法と、選択された値そのものを取得するプロパティがあります。また、Textプロパティを使うことで現在選択中の項目のテキストも取得できます。

プロパティ 説明
public int SelectedIndex { get; set; } ComboBoxコントロールで現在選択中の項目のインデックスを取得または設定します。未選択時は-1です。
public object SelectedItem { get; set; } ComboBoxコントロールで現在選択中の値を取得または設定します。
public string Text {get; set; } ComboBoxコントロールで現在のテキストを取得または設定します。

以下のように設定した、ComboBoxコントロールのSelectedIndexプロパティ、SelectedItemプロパティ、Textプロパティを表示するプログラムの実行結果を示します。

<ComboBox x:Name="comboBox" Grid.ColumnSpan="2" TextSearch.TextPath="Name">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Margin="2.5"/>
                <TextBlock Text="{Binding Age}" Margin="2.5"/>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

実行直後は、SelectedIndexプロパティが-1になっていることが確認できます。また、SelectedItemプロパティはnullでTextプロパティは空文字になっています。

f:id:okazuki:20140814201102p:plain

3番目の項目を選択すると以下のような表示になります。

f:id:okazuki:20140814201127p:plain

SelectedIndexプロパティが3番目を表す2になっている点と、SelectedItemプロパティが、選択項目のPersonオブジェクトになっていることが確認できます。TextプロパティはTextSearch.TextPath添付プロパティでNameプロパティを表示するようにしているため、Nameプロパティの値が表示されていることがわかります。

過去記事