いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

DataGridView入門記-11 (コンボボックスカラムのデータバインド)


DataGridViewComboBoxColumnは、セルにコンボボックスを表示する
タイプのカラムですが、TextBoxColumnとは違いこのカラムのタイプは
DataGridViewとは別にDataSourceを持つことが出来ます。


何のためのデータソースかというと、コンボボックス自体の値を
表示するためのデータソースになります。


で、当然DataGridView側のデータソースとコンボ側のデータソースとで
値をマッチして該当データを選択状態にする必要があります。
(たとえば、DataGridView側はAテーブルのデータでコンボは関連するBマスタテーブルのデータなど)


使用するDataGridViewComboBoxColumnのプロパティは以下です。

  • DataPropertyName
  • DataSource
  • DisplayMember
  • ValueMember


名前から大体見当は付くと思いますが、一応以下サンプルです。

// vim:set ts=4 sw=4 et ws is nowrap ft=cs:

using System;
using System.Drawing;
using System.Windows.Forms;

using Gsf.Samples.Utility;

namespace Gsf.Samples.DGV{

    /// <summary>
    /// DataGridViewComboBoxColumnのバインドサンプルです。
    /// </summary>
    public class DataGridViewSample11 : BaseForm{

        public DataGridViewSample11() : base("Gsf.Samples.DGV.DataGridViewSample11"){
            // nop;
        }

        protected override void InitializeComponents(){
            //////////////////////////////////////////////
            //
            // DataGridView & BindingSource
            //
            DataGridView grid = new DataGridView();

            grid.Dock                = DockStyle.Fill;
            grid.AutoGenerateColumns = false;
            grid.EditMode            = DataGridViewEditMode.EditOnEnter;

            grid.DataSource          = GetGridDataSource();

            DataGridViewColumn col = new DataGridViewTextBoxColumn();
            col.Name             = "id";
            col.DataPropertyName = "Id";
            col.HeaderText       = "ID";

            grid.Columns.Add(col);

            col = new DataGridViewTextBoxColumn();
            col.Name             = "name";
            col.DataPropertyName = "Name";
            col.HeaderText       = "名前";

            grid.Columns.Add(col);

            DataGridViewComboBoxColumn col2 = new DataGridViewComboBoxColumn();
            col2.Name             = "combo";
            // コンボデータコレクションに対しての引き当て対象データ
            // (DataGridView側のデータソースメンバを指定)
            //
            col2.DataPropertyName = "ComboId";
            // コンボボックスに対してのデータソース
            //
            // 通常、データベーステーブルであったり、enumであったり
            // 特定のコレクションだったりします。
            //
            col2.DataSource       = GetComboBoxDataSource();
            // コンボボックスに表示するデータメンバの指定
            // (コンボボックスのデータソースメンバ)
            //
            col2.DisplayMember    = "Value";
            // DataPropertyNameで指定されたデータに対応するDataSource側のメンバ
            // (コンボボックスのデータソースメンバ)
            //
            // この値が一致したものがコンボボックスの選択値になります。
            //
            col2.ValueMember      = "Id";
            col2.HeaderText       = "コンボ";

            grid.Columns.Add(col2);

            grid.DataError += delegate(object sender, DataGridViewDataErrorEventArgs e){
                //
                // コンボボックスの列のエラーの場合はエラーを補足し、セル上にエラーを表示
                //
                // (最後の行で、ありえないcombo_idを指定しているため表示時に必ずエラーとなる)
                //
                if(grid.Columns[e.ColumnIndex] == grid.Columns["combo"]){
                    grid[e.ColumnIndex, e.RowIndex].ErrorText = string.Format("列:{0}, 行:{1}  {2}", e.ColumnIndex, e.RowIndex, e.Exception.Message);
                    e.Cancel = true;
                }
            };

            grid.CellValidating += delegate(object sender, DataGridViewCellValidatingEventArgs e){
                //
                // セルのエラーテキストをクリア.
                //
                grid[e.ColumnIndex, e.RowIndex].ErrorText = "";
            };

            Controls.Add(grid);

            Size = new Size(500, 300);
        }

        /// <summary>
        /// DataGridView側のデータソースを返します.
        /// </summary>
        object GetGridDataSource(){
            BindingSource source = new BindingSource();

            source.DataSource = typeof(SampleData);

            Random r = new Random();
            for(int i = 0; i < 5; i++){

                int randomNumber = r.Next(0, 20);

                SampleData data = new SampleData();

                data.Id      = randomNumber;
                data.Name    = "name-" + randomNumber;
                data.ComboId = randomNumber;

                source.Add(data);
            }

            //
            // 最後に一致しないコンボデータを作成
            //
            SampleData lastData = new SampleData();
            lastData.Id      = 1000;
            lastData.Name    = "name-" + 1000;
            lastData.ComboId = 1000;

            source.Add(lastData);

            return source;
        }

        /// <summary>
        /// DataGridViewComboBoxColumn側のデータソースを返します.
        /// </summary>
        object GetComboBoxDataSource(){
            BindingSource source = new BindingSource();

            source.DataSource = typeof(ComboData);

            for(int i = 0; i < 20; i++){
                ComboData data = new ComboData();

                data.Id      = i;
                data.Value   = "コンボの値-" + i;

                source.Add(data);
            }

            return source;
        }

        [STAThread]
        static void Main(){
            ApplicationUtility.Launch("Gsf.Samples.DGV.DataGridViewSample11");
        }
    }

    /// <summary>
    /// DataGridView側のサンプルデータクラスです。
    /// </summary>
    class SampleData{
        int    _id;
        string _name;
        int    _comboId;

        public int Id{
            get{
                return _id;
            }
            set{
                _id = value;
            }
        }

        public string Name{
            get{
                return _name;
            }
            set{
                _name = value;
            }
        }

        public int ComboId{
            get{
                return _comboId;
            }
            set{
                _comboId = value;
            }
        }
    }

    /// <summary>
    /// DataGridViewComboBoxColumn側のデータクラスです。
    /// </summary>
    class ComboData{
        int    _id;
        string _value;

        public int Id{
            get{
                return _id;
            }
            set{
                _id = value;
            }
        }

        public string Value{
            get{
                return _value;
            }
            set{
                _value = value;
            }
        }
    }
}

================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。