ListBox(ComboBox)で内部の値とは別に表示する値を自由自在に変更する Part2

以前、こんなエントリを書いた。

ListBoxで内部の値とは別に表示する値を自由自在に変更する - posnum’s blog

もっと良い方法を見つけたのでメモ。

その方法とは、LINQで匿名型オブジェクトを使う。

以下のようなクラスがあったとする。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

ListBoxに表示用の匿名型オブジェクトを設定する。

// ListBoxに表示したい値を設定する
listBox1.DataSource = persons
    .Select(person => new { Display = string.Format(@"{0}, {1}", person.Name, person.Age), Value = person })
    .ToList();
listBox1.DisplayMember = "Display";
listBox1.ValueMember = "Value";

Selectの使い方がポイント。 newで匿名型オブジェクトを生成することができる。
メンバ名は何でも良いが、ここではわかりやすく Display と Value としてある。 Value に元のオブジェクトを設定しておくと、後で取り出せて超便利。
最後にToList()することで、匿名型オブジェクトのリストとなり、DataSource に設定できるようになる。
結構 ToList() を忘れてハマりがちなので注意。

ComboBoxでもまったく同じように扱える。

// ComboBoxも同様
comboBox1.DataSource = persons
    .Select(person => new { Display = string.Format(@"{0}, {1}", person.Name, person.Age), Value = person })
    .ToList();
comboBox1.DisplayMember = "Display";
comboBox1.ValueMember = "Value";

f:id:posnum:20150414215512j:plain

選択した値を取り出すのは以下のようにする。

// 選択されたオブジェクトそのものを取り出せる
var listBoxSelectedItem = (Person)listBox1.SelectedValue;
var comboBoxSelectedItem = (Person)comboBox1.SelectedValue;

MessageBox.Show(listBoxSelectedItem.Age + ", " + comboBoxSelectedItem.Age);

ここでは、SelectedValue を元の型でキャストするのを忘れないようにする。

いまところ、個人的にListBox(ComboBox)にオブジェクトを設定する場合のベストな方法である。
やはり C#LINQ をうまく使えると楽しい。