ListBoxやComboBoxのDataSourceプロパティには、文字列(String型)以外のオブジェクトのコレクションを指定することができます(同様に、ItemsプロパティのAddメソッド等を使って、文字列以外のオブジェクトを追加することもできます)。このときにリストに表示される項目の文字列は、そのオブジェクトのToStringメソッドが返す値(ただし、nullの時は空の文字列)となります。
もしToStringではなく、あるプロパティが返す値を表示したいのであれば、そのプロパティの名前をDisplayMemberプロパティに指定します。
例えば、Encoding.GetEncodingsが返すエンコーディングの配列をListBoxに追加し、項目にエンコーディングの表示名(Encoding.DisplayNameプロパティ)を表示させるには、次のようにします。
'DisplayNameプロパティを項目の表示に利用する ListBox1.DisplayMember = "DisplayName" 'エンコーディングの配列をListBox1のデータソースに設定する ListBox1.DataSource = System.Text.Encoding.GetEncodings()
//DisplayNameプロパティを項目の表示に利用する ListBox1.DisplayMember = "DisplayName"; //エンコーディングの配列をListBox1のデータソースに設定する ListBox1.DataSource = System.Text.Encoding.GetEncodings();
補足:DisplayMemberプロパティはリストに項目を追加する前(DataSourceプロパティに格納する前)に設定すべきです。DataSourceプロパティ格納後にDisplayMemberプロパティを設定すると、リストに項目を表示しなおすための時間がかかるため、遅くなります。
ValueMemberプロパティは、SelectedValueプロパティで取得、設定できるようにする値を指定するためのものと考えてよいでしょう。SelectedValueプロパティで、現在選択されている項目のValueMemberプロパティで指定されたプロパティの値を取得できます。また、指定された値をValueMemberプロパティで指定されたプロパティにもつ項目を探して選択するために、SelectedValueプロパティを使うこともできます。特に後者の使い方は重宝します。
ただしDataSourceプロパティを設定せずに、ItemsプロパティのAddメソッドによりオブジェクトを追加したときは、ValueMemberプロパティにかかわらず、SelectedValueプロパティは常にnull(VB.NETでは、Nothing)を返すようです。
補足:DisplayMemberが指定されていないときにValueMemberを設定すると、DisplayMemberも同じ値になります。
補足:ValueMemberが指定されていないとき、SelectedValueはそのオブジェクトのToStringメソッドが返す値になるとMSDNにはありますが、私が試した限りではそうはならず、SelectedItemプロパティと同じ値を返すようでした。
以下の例では、先の例に追加して、ValueMemberプロパティに"CodePage"を指定しています。このようにすると、「ListBox1.SelectedValue」で現在選択されているエンコーディングのコードページを取得したり、コードページでエンコーディングを選択したりすることができます。
'DisplayNameプロパティを項目の表示に利用する ListBox1.DisplayMember = "DisplayName" 'CodePageプロパティをSelectedValueで取得、設定できる値に利用する ListBox1.ValueMember = "CodePage" 'エンコーディングの配列をListBox1のデータソースに設定する ListBox1.DataSource = System.Text.Encoding.GetEncodings() 'コードページが932の項目を選択する ListBox1.SelectedValue = 932
//DisplayNameプロパティを項目の表示に利用する ListBox1.DisplayMember = "DisplayName"; //CodePageプロパティをSelectedValueで取得、設定できる値に利用する ListBox1.ValueMember = "CodePage"; //エンコーディングの配列をListBox1のデータソースに設定する ListBox1.DataSource = System.Text.Encoding.GetEncodings(); //コードページが932の項目を選択する ListBox1.SelectedValue = 932;
DisplayMemberプロパティに関連して、追記します。.NET Framework 2.0からは、FormatStringプロパティやFormatイベントを使って、リストに表示する文字列の書式を指定することができます。これらを使うためには、FormattingEnabledプロパティをtrueにする必要があります。
FormatStringプロパティには、リストにどのように表示するかを、書式指定文字列を使って指定します。書式指定文字列については、「書式を指定して数値を文字列に変換する」や「日時(DateTimeオブジェクト)を文字列に変換する」などをご覧ください。
FormatStringプロパティで指定された書式は、DisplayMemberプロパティで指定された項目の値に対して適応され、表示されます。
以下の例では、エンコーディングのCodePageプロパティを、"00000"という書式で表示しています。
ListBox1.DisplayMember = "CodePage" ListBox1.DataSource = System.Text.Encoding.GetEncodings() 'FormatStringの設定を有効にする ListBox1.FormattingEnabled = True '書式を指定する ListBox1.FormatString = "00000"
ListBox1.DisplayMember = "CodePage"; ListBox1.DataSource = System.Text.Encoding.GetEncodings(); //FormatStringの設定を有効にする ListBox1.FormattingEnabled = true; //書式を指定する ListBox1.FormatString = "00000";
Formatイベントを使えば、もっと複雑なことができます。Formatイベントハンドラで取得できるListControlConvertEventArgsオブジェクトのValueプロパティに、リストに表示させたい文字列を設定することができます。
以下の例では、Formatイベントを使って、リストにDisplayNameとCodePageを表示するようにしています。
'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles MyBase.Load ListBox1.DisplayMember = "CodePage" ListBox1.DataSource = System.Text.Encoding.GetEncodings() 'FormatStringの設定を有効にする ListBox1.FormattingEnabled = True End Sub 'ListBox1のFormatイベントハンドラ Private Sub ListBox1_Format(ByVal sender As Object, _ ByVal e As ListControlConvertEventArgs) _ Handles ListBox1.Format '文字列が要求されているときだけ変える If e.DesiredType Is GetType(String) Then 'DisplayNameとCodePageを表示するように変更する e.Value = CType(e.ListItem, System.Text.EncodingInfo).DisplayName + _ " : " + e.Value.ToString() End If End Sub
//フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { ListBox1.DisplayMember = "CodePage"; ListBox1.DataSource = System.Text.Encoding.GetEncodings(); //FormatStringの設定を有効にする ListBox1.FormattingEnabled = true; //Formatイベントハンドラを追加 ListBox1.Format += new ListControlConvertEventHandler(ListBox1_Format); } //ListBox1のFormatイベントハンドラ private void ListBox1_Format(object sender, ListControlConvertEventArgs e) { //文字列が要求されているときだけ変える if (e.DesiredType == typeof(string)) { //DisplayNameとCodePageを表示するように変更する e.Value = ((System.Text.EncodingInfo)e.ListItem).DisplayName + " : " + e.Value.ToString(); } }
FormatStringプロパティが指定されている場合でも、Formatイベントの結果が優先されるようです。ただし、FormatイベントでValueプロパティの値を変更しなかった場合は、FormatStringプロパティの書式が使われます。
また、FormatイベントのValueプロパティで取得できる値は、FormatStringプロパティが適用されていない値となるようです。