Architect's Log

I'm a Cloud Architect. I'm highly motivated to reduce toils with driving DevOps.

DataGridViewのDataBindingCompleteイベントが複数回発生する現象に対処する

DataGridViewのDataBindingCompleteイベントが複数回発生する現象に遭遇しました。
検索で次のブログがヒットしました。
DataGridView の DataBindingComplete イベントの発生回数

コード内で DataSource と DataMember の設定を行うとして、DataSource → DataMember の順で設定すると、DataBindingComplete イベントは三回発生する。
これを DataMember → DataSource の順で設定すると一回のみ発生する。
基本的に一回しか発生させたくないため、設定順序に注意。

検証

検証してみましょう。

DataSource→DataMemberの順で設定
using System;
using System.Data;
using System.Windows.Forms;

namespace DataGridView {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();

            dataGridView1.DataBindingComplete += (s, e) => Console.WriteLine("Complete!");

            this.Shown += (s, e) => {
                DataSet ds = new DataSet();
                DataTable dt = new DataTable("hoge");
                ds.Tables.Add(dt);
                dt.Columns.Add(new DataColumn("fuga", typeof(string)));
                dt.Rows.Add("a");

                // DataMemberを後に設定する。
                dataGridView1.DataSource = ds;
                dataGridView1.DataMember = "hoge";
            };
        }
    }
}


Complete!
Complete!
Complete!
3回イベントが発生しました。

DataMember→DataSourceの順で設定
using System;
using System.Data;
using System.Windows.Forms;

namespace DataGridView {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();

            dataGridView1.DataBindingComplete += (s, e) => Console.WriteLine("Complete!");

            this.Shown += (s, e) => {
                DataSet ds = new DataSet();
                DataTable dt = new DataTable("hoge");
                ds.Tables.Add(dt);
                dt.Columns.Add(new DataColumn("fuga", typeof(string)));
                dt.Rows.Add("a");

                // DataMemberを先に設定する。
                dataGridView1.DataMember = "hoge";
                dataGridView1.DataSource = ds;
            };
        }
    }
}


Complete!
イベントは1回しか発生しませんでした。

DataMemberを設定できない場合は?

IListなどDataMemberを設定できない(設定する必要がない)場合は、nullを設定すればOKです。

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace DataGridView {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();

            dataGridView1.DataBindingComplete += (s, e) => Console.WriteLine("Complete!");

            this.Shown += (s, e) => {
                List<string> list = new List<string> { "hoge" };

                // DataMemberを先に設定する。
                dataGridView1.DataMember = null;
                dataGridView1.DataSource = list;
            };
        }
    }
}


Complete!