DataGridView の描画が遅いときに気をつけること

DataGridView で、

のプロパティが、自動に設定されているとき、

  • 行や列の追加
  • セルに値を設定

すると、描画が遅くなる。

以下の例では、50 x 50 で 9.2 秒かかった。

f:id:tt195361:20150612082645p:plain

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace DataGridViewSizeModeAndSpeed
{
    public partial class Form1 : Form
    {
        private const int ColumnCount = 50;
        private const int RowCount = 50;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var sw = new Stopwatch();
            sw.Start();

            // サイズ設定が自動のとき、行や列を追加したり、セルに値を設定すると、実行が遅くなる。
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;

            AddColumns();
            AddRows();
            SetValues();

            sw.Stop();
            label1.Text = String.Format("所要時間: {0}", sw.Elapsed);
        }

        private void AddColumns()
        {
            for (int index = 0; index < ColumnCount; ++index)
            {
                AddColumn(index + 1);
            }
        }

        private void AddColumn(int columnNumber)
        {
            var column = new DataGridViewColumn();
            column.Name = columnNumber.ToString();
            column.CellTemplate = new DataGridViewTextBoxCell();
            dataGridView1.Columns.Add(column);
        }

        private void AddRows()
        {
            for (int index = 0; index < RowCount; ++index)
            {
                dataGridView1.Rows.Add();
            }
        }

        private void SetValues()
        {
            for (int columnIndex = 0; columnIndex < ColumnCount; ++columnIndex)
            {
                for (int rowIndex = 0; rowIndex < RowCount; ++rowIndex)
                {
                    String value = String.Format("{0}-{1}", columnIndex + 1, rowIndex + 1);
                    dataGridView1[columnIndex, rowIndex].Value = value;
                }
            }
        }
    }
}

順番を、

  1. 自動サイズ設定しない。
  2. 行や列を追加、セルに値を設定。
  3. 自動サイズ設定する。

に変更すると、描画時間は 0.15 秒になった。

f:id:tt195361:20150612083603p:plain

        private void Form1_Load(object sender, EventArgs e)
        {
            var sw = new Stopwatch();
            sw.Start();

            // 行や列を追加したり、セルに値を設定するときは、自動サイズ設定しない。
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;

            AddColumns();
            AddRows();
            SetValues();

            // 自動でサイズを設定するのは、行や列を追加したり、セルに値を設定した後にする。
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
            dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;

            sw.Stop();
            label1.Text = String.Format("所要時間: {0}", sw.Elapsed);
        }