studio Odyssey




スタジオ日誌

日誌的なもの

2010.07.28

非バインドのDataGridViewで高速に行を追加する

Written by
しゃちょ
Category
C#

 非バインドのDataGridViewで、普通にAddしていくと、すげー遅いんで、なんとか描画を止めて追加とか出来ないかなぁと思っていろいろ探していたんだが、あんまりいい方法がない。

 初心に返って、RowsのAddRangeで追加すればいいのだが、これが、params DataGridViewRow[] なんだよね。

 どうやって、DataGridViewのカラムの状態を作るのかわからなかったのだが、ちょっと調べてみると、DataGridViewRowに、CreateCellsというメソッドが。

 引数にはDataGridViewを取るんだけど、これで、カラムの状態がコピーされるのね。Alternateもちゃんと行くし、これでAddRangeで追加すれば、かなり高速。

 以下、コード。こんな書き方しないだろうけどね。

public partial class TestDraw : Form
{
    private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
    private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
    private System.Windows.Forms.DataGridViewTextBoxColumn Column3;

    public TestDraw()
    {
        InitializeComponent();

        this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn()
        {
            HeaderText = "Column1",
            Name = "Column1",
        };

        this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn()
        {
            HeaderText = "Column2",
            Name = "Column2",
        };
        this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn()
        {
            HeaderText = "Column3",
            Name = "Column3",
        };

        this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[]
        {
            this.Column1,
            this.Column2,
            this.Column3
        });
    }

    const int LoopCount = 10000;

    private void button1_Click(object sender, EventArgs e)
    {
        this.dataGridView1.Rows.Clear();

        Stopwatch w = new Stopwatch();
        w.Start();

        for (int i = 0; i < LoopCount; i++)
        {
            this.dataGridView1.Rows.Add(new object[] { "A", "B", "C" });
        }

        w.Stop();
        Console.WriteLine(w.ElapsedTicks);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        this.dataGridView1.Rows.Clear();

        Stopwatch w = new Stopwatch();
        w.Start();

        DataGridViewRow[] list = new DataGridViewRow[LoopCount];

        for (int i = 0; i < LoopCount; i++)
        {
            DataGridViewRow row = new DataGridViewRow();
            row.CreateCells(this.dataGridView1);
            row.SetValues(new object[] { "A", "B", "C" });
            list[i] = row;
        }

        this.dataGridView1.Rows.AddRange(list);

        w.Stop();
        Console.WriteLine(w.ElapsedTicks);
    }
}

 計測結果はこんなモン。

7742172812
7312817332
7246831260
7391705720
7446151504
7506687032
7261821236
7616118364
7390859600
7577380856

1515845732
1397257748
1767553412
1630484896
1452826976
1729132656
1444430796
1826411688
1446485192
1742929448


トラックバックURL

http://blog.studio-odyssey.net/cgi-bin/mt/mt-tb.cgi/446

コメント[1]

kodama   2014.10.28 14:21 | 返信

4年も経ってのコメント相済みませぬ。vb.net2010 expressで datagridview.rows.addrangeのパラメータ:columnsコレクションをどう与えてよいかMSDNみても分からなかったので、参考にさせていただきました。
vb.netの場合、this.dataGridView1.Rows.AddRange(list.toArray) listを配列に変換すると通りました。落ち着いてよく考えれば、list-->toArray-->rangeに代入は常套手段でした。
ありがとうございました。


コメントする