【.NET】コンボボックスに表示する文字列と実際の値(内部的なID、コード、キーなど)とをうまく対応させる その2
VB.NETやC#でコンボボックスの項目と内部的に保持する実際の値を対応させる別の方法です。
(【.NET】コンボボックスに表示する文字列と実際の値(内部的なID、コード、キーなど)とをうまく対応させる その1 からの続きです。)
方法2:DataSourceを使用する
DataSourceプロパティを使用すると、簡単に表示上の値と内部的な値を区別して拾うことができます。
前回と同じように、下表のような対応があり、たとえばコンボボックスで「みかん」が選択された場合に、ID「002」という値を拾いたいというケースで考えます。
ID | 表示名称 |
---|---|
001 | リンゴ |
002 | みかん |
003 | メロン |
004 | ぶどう |
プログラムの見た目は、前回と一緒です。
DataTableを作成してComboBoxのDataSourceに設定する
まずは、FormのLoadイベント内で(Loadじゃなくても良いですが、設定したい場所で)、上記の表と同じ感じのDataTableを作成してDataSourceプロパティにセットします。
'VB.NETのサンプル Private Sub Form1_Load( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load 'DataTableオブジェクトを用意 Dim fruiteTable As New DataTable() 'DataTableに列を追加 fruiteTable.Columns.Add("ID", GetType(String)) fruiteTable.Columns.Add("NAME", GetType(String)) '行を追加する処理(面倒なので一旦配列に文字列を用意してループで…) '配列の用意 Dim rowDataArray As String(,) = _ {{"001", "リンゴ"}, _ {"002", "みかん"}, _ {"003", "メロン"}, _ {"004", "ぶどう"}} For i As Integer = 0 To rowDataArray.GetLength(0) - 1 '新しい行を作成 Dim row As DataRow = fruiteTable.NewRow() '各列に値をセット row("ID") = rowDataArray(i, 0) '001など row("NAME") = rowDataArray(i, 1) 'リンゴなど 'DataTableに行を追加 fruiteTable.Rows.Add(row) Next fruiteTable.AcceptChanges(); 'コンボボックスのDataSourceにDataTableを割り当てる comboFruit.DataSource = fruiteTable '表示される値はDataTableのNAME列 comboFruit.DisplayMember = "NAME" '対応する値はDataTableのID列 comboFruit.ValueMember = "ID" End Sub
//C#のサンプル private void Form1_Load(object sender, EventArgs e) { //DataTableオブジェクトを用意 DataTable fruiteTable = new DataTable(); //DataTableに列を追加 fruiteTable.Columns.Add("ID", typeof(string)); fruiteTable.Columns.Add("NAME", typeof(string)); //行を追加する処理(面倒なので一旦配列に文字列を用意してループで…) //配列の用意 string[,] rowDataArray = {{"001", "リンゴ"}, {"002", "みかん"}, {"003", "メロン"}, {"004", "ぶどう"}}; for(int i = 0; i < rowDataArray.GetLength(0); i++ ) { //新しい行を作成 DataRow row = fruiteTable.NewRow(); //各列に値をセット row["ID"] = rowDataArray[i, 0]; //001など row["NAME"] = rowDataArray[i, 1]; //リンゴなど //DataTableに行を追加 fruiteTable.Rows.Add(row); } fruiteTable.AcceptChanges(); //コンボボックスのDataSourceにDataTableを割り当てる comboFruit.DataSource = fruiteTable; //表示される値はDataTableのNAME列 comboFruit.DisplayMember = "NAME"; //対応する値はDataTableのID列 comboFruit.ValueMember = "ID"; }
ユーザーに選択された値を取得する
SelectedValueプロパティを参照することで、ValueMemberプロパティで設定した列の値を取得できます。
'VB.NETのサンプル Private Sub comboFruit_SelectedValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles comboFruit.SelectedValueChanged '選択されていればSelectedValueに入っている If comboFruit.SelectedIndex <> -1 Then 'ラベルに表示 selectedId.Text = comboFruit.SelectedValue.ToString() End If End Sub
//C#のサンプル private void comboFruit_SelectedValueChanged( object sender, EventArgs e) { //選択されていればSelectedValueに入っている if(comboFruit.SelectedIndex != -1) { //ラベルに表示 selectedId.Text = comboFruit.SelectedValue.ToString(); } }
逆にプログラム中でコードからアイテムを選択する場合は、
'VB.NETのサンプル comboFruit.SelectedValue = "001"
//C#のサンプル comboFruit.SelectedValue = "001";
のように書くことができます。
ところで、DataSourceにDataTableを設定する例は上述したようなものです(良く使うパターンでしょう)が、設定できるのはDataTableだけではありません。
補足:DataSourceに設定できるもの
DataSourceには、IList インターフェイスを実装するオブジェクトであれば何でも設定可能です。
たとえば、配列(Array)や、ArrayListなども設定可能です。
ただし、それらの要素となるオブジェクトは、ValueMemberとDisplayMemberに設定した文字列と同名のプロパティか、設定した文字列で参照できるインデクサを持っている必要があります。
(.NET Framework 2.0で試したところ、プロパティとインデクサの両方が存在するときは、プロパティが優先されるようです。)
配列をDataSourceにする例
以下は、IDとNAMEというプロパティを持つ独自のクラスを定義して、その配列をDataSourceに設定する例です。
'VB.NETのサンプル 'コンボボックスに追加する項目となるクラス Public Class MyComboBoxItem Private m_id As String = "" Private m_name As String = "" '実際の値 '(ValueMemberに設定する文字列と同名にする) Public Property ID() As String Set(ByVal value As String) m_id = value End Set Get Return m_id End Get End Property '表示名称 '(DisplayMemberに設定する文字列と同名にする) Public Property NAME() As String Set(ByVal value As String) m_name = value End Set Get Return m_name End Get End Property End Class
//C#のサンプル //コンボボックスに追加する項目となるクラスの定義 public class MyComboBoxItem { private string m_id = ""; private string m_name = ""; //実際の値 //(ValueMemberに設定する文字列と同名にする) public string ID { set { m_id = value; } get { return m_id; } } //表示名称 //(DisplayMemberに設定する文字列と同名にする) public string NAME { set { m_name = value; } get { return m_name; } } }
上のように定義したMyComboBoxItemクラスを配列にし、コンボボックスのDataSourceにセットします。
'VB.NETのサンプル '配列を作成してDataSourceにセットする例 '配列を作成 Dim mySource(3) As MyComboBoxItem mySource(0) = New MyComboBoxItem mySource(0).ID = "001" mySource(0).NAME = "リンゴ" mySource(1) = New MyComboBoxItem mySource(1).ID = "002" mySource(1).NAME = "みかん" mySource(2) = New MyComboBoxItem mySource(2).ID = "003" mySource(2).NAME = "メロン" mySource(3) = New MyComboBoxItem mySource(3).ID = "004" mySource(3).NAME = "ぶどう" '表示される値はNAMEプロパティ comboFruit.DisplayMember = "NAME" '対応する値はIDプロパティ comboFruit.ValueMember = "ID" 'DataSourceに上で作成した配列をセット comboFruit.DataSource = mySource
//C#のサンプル //配列を作成してDataSourceにセットする例 //配列を作成 MyComboBoxItem[] mySource = new MyComboBoxItem[4]; mySource[0] = new MyComboBoxItem(); mySource[0].ID = "001"; mySource[0].NAME = "リンゴ"; mySource[1] = new MyComboBoxItem(); mySource[1].ID = "002"; mySource[1].NAME = "みかん"; mySource[2] = new MyComboBoxItem(); mySource[2].ID = "003"; mySource[2].NAME = "メロン"; mySource[3] = new MyComboBoxItem(); mySource[3].ID = "004"; mySource[3].NAME = "ぶどう"; //表示される値はNAMEプロパティ comboFruit.DisplayMember = "NAME"; //対応する値はIDプロパティ comboFruit.ValueMember = "ID"; //DataSourceに上で作成した配列をセット comboFruit.DataSource = mySource;
これでもDataTableをDataSourceにしたのと同様の動作になります。現在選択されているIDは、SelectedValueプロパティで取得可能です。
関連図書
関連記事
TrackBack URL :
Comments (0)