DataGrid への表示は、VB6 の頃から遅くて、表示更新をしないと早くなるという噂(けど真実)があったりします。
で、.NET になって DataGridView への DataSource プロパティへのバインドをすると早くなる、ってのが定番なんですが(セルへちまちま貼り付けるよりも早くなります…が、測定はしてないので、そのうちに)、なぜか、DataSource プロパティへのバインドをしているのに、とてつもなく遅くなる現象が発覚したので、晒します。
1.10 カラムある DataGridView を作ります。
2.データを作成
/// <summary>
/// データ作成
/// </summary>
/// <returns></returns>
private List<Data> MakeData()
{
List<Data> lst = new List<Data>();
for (int i = 0; i < 3000; i++)
{
Data d = new Data();
d.Col1 = i.ToString();
d.Col2 = DateTime.Now.ToString();
d.Col3 = DateTime.Now.ToString();
d.Col4 = DateTime.Now.ToString();
d.Col5 = DateTime.Now.ToString();
d.Col6 = DateTime.Now.ToString();
d.Col7 = DateTime.Now.ToString();
d.Col8 = DateTime.Now.ToString();
d.Col9 = DateTime.Now.ToString();
d.Col10= DateTime.Now.ToString();
lst.Add(d);
}
return lst;
3.データバインド
private void button1_Click(object sender, EventArgs e)
{
var lst = MakeData();
// 自動でカラムを作らない
dataGridView1.AutoGenerateColumns = false;
// 列幅はそのまま
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing;
Stopwatch sw = new Stopwatch();
sw.Start();
dataGridView1.DataSource = lst;
sw.Stop();
MessageBox.Show(string.Format("経過時間:{0} msec", sw.ElapsedMilliseconds));
// 10 msec 程度
}
普通に作るととても早いのですが…
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
このように、AutoSizeToAllHeaders を指定して列幅を自動で作成しようとすると。
private void button1_Click(object sender, EventArgs e)
{
var lst = MakeData();
// 自動でカラムを作らない
dataGridView1.AutoGenerateColumns = false;
// 列幅を自動調節する
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
Stopwatch sw = new Stopwatch();
sw.Start();
dataGridView1.DataSource = lst;
sw.Stop();
MessageBox.Show(string.Format("経過時間:{0} msec", sw.ElapsedMilliseconds));
// 4 分経ってもまだ終わりません。
}
ってな具合に、1000 倍ぐらい遅くなります。
想像するに、DataSource プロパティでバインドしたデータが、1 件加わるごとに AutoSizeToAllHeaders で列幅を調節している感じなんですよね。なので、一度、EnableResizing で計算しないようにしてから、後で AutoSizeToAllHeaders を指定します。
private void button1_Click(object sender, EventArgs e)
{
var lst = MakeData();
// 自動でカラムを作らない
dataGridView1.AutoGenerateColumns = false;
// 列幅はそのままに変える
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing;
Stopwatch sw = new Stopwatch();
sw.Start();
dataGridView1.DataSource = lst;
// 全て入力した後に列幅を自動調節する
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
sw.Stop();
MessageBox.Show(string.Format("経過時間:{0} msec", sw.ElapsedMilliseconds));
// 108 msec 高速に動作する
}



解決しました。ありがとうm(__)m
解決してよかったです。
テストのときに数十行では大したことがなくて、実際のデータで数千行を表示させたらとてつもなく遅くなった、というパターンに陥ります。
なぜか、DataGridView って1行追加するごとにヘッダの幅を再計算&再描画しているんですよね。。。ってことで、意外とハマります。