システム開発・Webサイト構築 プラスラス

2008/2/9 土曜日

【.NET】コンボボックスに表示する文字列と実際の値(内部的なID、コード、キーなど)とをうまく対応させる その2

このエントリーを含むはてなブックマーク Yahoo!ブックマークに登録 Google ブックマーク del.icio.us

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なども設定可能です。

ただし、それらの要素となるオブジェクトは、ValueMemberDisplayMemberに設定した文字列と同名のプロパティか、設定した文字列で参照できるインデクサを持っている必要があります。

(.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プロパティで取得可能です。

関連図書

ずばりわかる!VB&C#―プログラミングの基礎はこれで万全 (日経BPパソコンベストムック) 速効解決!逆引きハンドブック Visual Basic―2005対応 (テクニカルTipsシリーズ) 速効解決!逆引きハンドブックVisual C# (テクニカルTipsシリーズ)

関連記事

Filed under: C#,Programming,VB.NET — Nakai @ 22:02:42

コメントはまだありません »

コメントはまだありません。

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする

HTML convert time: 0.790 sec. Powered by WordPress