ListBoxで内部の値とは別に表示する値を自由自在に変更する
2015/04/14
別の方法を見つけたのでエントリを書いた
ListBox(ComboBox)で内部の値とは別に表示する値を自由自在に変更する Part2 - posnum’s blog
最も単純な方法としては、 ListBox に DataSource を設定し、DisplayMember プロパティに表示したいメンバを設定する。
例えば、以下のクラスがあったとする。
class Person { public string Name { get; set; } public int Age { get; set; } }
以下のように ListBox の DataSource プロパティに設定し、 DisplayMember に "Name" を指定してやれば良い。
var persons = new Person[] { new Person { Name = "Smith", Age = 20 }, new Person { Name = "John", Age = 35 }, new Person { Name = "Mike", Age = 15 } }; listBox1.DataSource = persons; listBox1.DisplayMember = "Name";
ただ、この方法だと "Name" か "Age" をそのまま表示することしかできない。 Smith, 20 のように表示したいこともある。 (この例だと ListBox を使うのは適切ではないかもしれないが)
方法は大きく2つあり、ひとつは Person クラスで ToString() メソッドをオーバーライドしてやれば良い。
ListBox などは、DisplayMember を指定していない場合、 設定されているクラスの ToString() メソッドを呼び出して表示に利用している。
ただ、この方法は場合によってはおおげさだ。 表示のためだけにクラスをいじりたくない場合も多いだろう。
オススメなのがもうひとつの方法。
Formatイベントを利用する方法である。 これを用いることで実質なんでも表示できるようになる。
VisualStudioでプロパティウィンドウから設定することができる。
e.ListItem にリストの項目のオブジェクトが入っており、 e.Value に表示したい内容を設定できる。 ここでは string.Format を使ってみた。
private void Form1_Load(object sender, EventArgs e) { var persons = new Person[] { new Person { Name = "Smith", Age = 20 }, new Person { Name = "John", Age = 35 }, new Person { Name = "Mike", Age = 15 } }; listBox1.DataSource = persons; } private void listBox1_Format(object sender, ListControlConvertEventArgs e) { var person = (Person)e.ListItem; e.Value = string.Format(@"{0}, {1}", person.Name, person.Age); }
この方法が素晴らしいのは、表示するためのクラスを作成したり、 元のクラスをいじったりしないことである。
非常に便利。
参考: DisplayMemberとValueMemberプロパティについて: .NET Tips: C#, VB.NET