.NETには、ComboBoxやListBoxという便利なクラスがある。
これ、一見String型しか入らないように見えるけども、実はこれらのコレクションにはObject型をAddすることが出来る。Object型が入るということは、Objectを継承したクラスすべてをぶち込むことが出来るということだ。そもそも、クラスは自動的にObjectを継承するから、すべてのクラスをぶち込むことが出来ることと同意である。
ぶち込んだら、表示はどうなるのか
たとえば、ユーザ定義のクラスをぶち込んだ場合、表示はどうなるのか。これは、ToString()が呼ばれた結果が表示されるようだ。ToString()とは、Objectで定義されている最も有名なメソッドの一つである。
何がいいたいかというと、ToString()をoverrideするメソッドを用意すればいいのである。
ところで、何が便利なのか
IDと値を関連付けた状態で保持したいときなどに便利。それだけに限らず、複数の選択肢から一つをユーザに選択させたい場合、その中でToString()をoverrideするだけで、そのままComboBoxにぶち込めるのである。
クラス定義例
/// <summary> /// キーと値を関連付けるクラス /// リストボックスや、コンボボックスのItemsにAddするときに使用する /// </summary> class KeyValuePair { int key; string val; /// <summary> /// キーと値を設定するコンストラクタ /// </summary> /// <param name="key">キー</param> /// <param name="val">値</param> public KeyValuePair(int key, string val) { this.key = key; this.val = val; } /// <summary> /// キー /// </summary> public int Key { get { return key; } set { key = value; } } /// <summary> /// 値 /// </summary> public string Value { get { return val; } set { val = value; } } /// <summary> /// 表示される値 /// </summary> /// <returns></returns> public override string ToString() { return val; } }
ちなみに言うと、KeyValuePairというクラスは、.NETに(機能は似て非なるけども)標準で用意してある。名前が被って気に食わないときは、変えるといい。
追記(2010/01/05 12:38)
ここまで小規模なクラスなら、コメントで出てる方法の方が良いかもしれない。しかし、今まで使っていたユーザ定義のクラス要素をコンボボックスに入れて処理したい時などは、ToString()を実装するだけで(コンボボックスに格納するためのクラスなどを別途定義する必要などなく)使えてしまうので、ひょっとしたら楽かもしれない。好みによって、コメントいただいた方法と使い分けると良いかもしれない。コメントの方法だと、内部実装を変えたりしたとき(例えばプロパティ名を変えたり……これは外部に提供するプロパティが使えなくなるということだから外部実装と言えるかも)に、VisualStudioなら便利なリファラという機能で一気に名前変更できるが、文字列中で指定したプロパティ名までは変更されないと思う。そのため、ToString()で表示される内容を提供すると、一括して決めておくほうが、後々の管理が楽かなというなんとなく感覚的な印象。
使い方
入れる
for (int i = 0; i < data.Length; i++) { KeyValuePair kvp = new KeyValuePair(data[i].id, data[i].name); combobox.Items.Add(kvp); }
まぁこんな感じで。
出す
int key = ((KeyValuePair)this.combobox.SelectedItem).Key;
取り出すときは、普通にキャストすればいい。
ComboBox.DisplayMemberプロパティで表示するプロパティ名を指定してあげれば組込のKeyValuePairでいけますよ。
コメントありがとうございます。
確かに、KeyとValueの2つの値をセットとして格納したい、という状況に限定すれば、そのような方法が使えますね。
一つ勉強になりました、ありがとうございます。
暇を見つけて追記しておきますね。