none
DataGridView コントロール(仮想モード)でスクロール性能を良くしたい RRS feed

  • 質問

  • C#でWindowsフォームDataGridView コントロールを使用したアプリを開発しています。カラム数は10列程度ですが、行数が数千万行とデータ量が巨大なので「仮想モード」を使用していますが、スクロール性能(特にスクロールバーでの表示位置移動)が悪く、とても使いものになりません。

    このアプリは下記のページを参考にしました。グリッドの行数は全データの行数ですが、表示する行数は数十行であり、表示に必要なデータだけをグリッドに与える方式です。

    http://msdn.microsoft.com/ja-jp/library/ms171624(v=VS.80).aspx

    スクロール性能は以下のソースコードで試しています。グリッドの行数に比例してメモリ消費量も増えています。

    using System;

    using System.Drawing;

    using System.Windows.Forms;

    namespace WindowsFormsApplication1 {

        public class VirtualJustInTimeGrid : System.Windows.Forms.Form {

            private DataGridView dataGridView1 = new DataGridView();

            protected override void OnLoad(EventArgs e) {

                this.AutoSize = true;

                this.Controls.Add(this.dataGridView1);

                this.Text = "DataGridView virtual-mode just-in-time";

                this.dataGridView1.Columns.Add("column_A", "column_A");

                this.dataGridView1.Columns.Add("column_B", "column_B");

                this.dataGridView1.Columns.Add("column_C", "column_C");

                this.dataGridView1.Columns.Add("column_D", "column_D");

                this.dataGridView1.Columns.Add("column_E", "column_E");

                this.dataGridView1.Columns.Add("column_F", "column_F");

                this.dataGridView1.Columns.Add("column_G", "column_G");

                this.dataGridView1.Columns.Add("column_H", "column_H");

                //this.dataGridView1.RowCount = 1000000;  // 表示まで 速い、スクロールバー操作 速い、行/頁スクロール性能 速い

                //this.dataGridView1.RowCount = 5000000;  // 表示まで 遅い、スクロールバー操作 まあまあ、行/頁スクロール性能 速い

                //this.dataGridView1.RowCount = 10000000; // 表示まで 遅い、スクロールバー操作 まあまあ、行/頁スクロール性能 速い

                //this.dataGridView1.RowCount = 30000000; // 表示まで 超遅、スクロールバー操作 超遅、行/頁スクロール性能 まあまあ

                this.dataGridView1.RowCount = 50000000;   // 表示まで 超遅、スクロールバー操作 超遅、行/頁スクロール性能 まあまあ

                //this.dataGridView1.RowCount = 80000000; // 例外発生

                this.dataGridView1.Size = new Size(800, 400);

                this.dataGridView1.Dock = DockStyle.Fill;

                this.dataGridView1.VirtualMode = true;

                this.dataGridView1.ReadOnly = true;

                this.dataGridView1.AllowUserToAddRows = false;

                this.dataGridView1.AllowUserToOrderColumns = false;

                this.dataGridView1.SelectionMode =

                    DataGridViewSelectionMode.FullRowSelect;

                this.dataGridView1.CellValueNeeded += new

                    DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);

                this.dataGridView1.AutoResizeColumns(

                    DataGridViewAutoSizeColumnsMode.DisplayedCells);

                base.OnLoad(e);

            }

            private void dataGridView1_CellValueNeeded(object sender,

                    DataGridViewCellValueEventArgs e) {

                e.Value = e.RowIndex + "_" + e.ColumnIndex;

            }

            [STAThreadAttribute()]

            public static void Main() {

                Application.Run(new VirtualJustInTimeGrid());

            }

        }

    }

    環境はOS:Windows7 32ビット、CPU:Intel Core2 T7200 2GHz、メモリ:2GBです。64ビット環境にすれば性能は改善するかも知れませんが、現在の環境でも快適にスクロールする方法を考えたいのです。

    仮想グリッドで行数に比例してメモリ消費量が増えるのはチョット納得できないので、上記ソースコードは実装がまずいのかも知れません。それとも、コントロール側の実装の問題か。

    スクロールバーの操作で表示位置を移動させた時、それに遅れなく表示する性能を期待しているのですが良い方法はありませんか?、自分で独自に仮想グリッドを実装するだけの力はないのです・・・

    よろしくご教示願います。


    2010年4月15日 7:44

回答

  • DataGridViewのプロパティで、

    CellBorderStyleの属性を none にしたら、どうですか?

     

    セルの境界線が無くなったら、パフォーマンスはずいぶん上がりますが~~

    • 回答の候補に設定 山本春海 2010年4月28日 9:54
    • 回答としてマーク 山本春海 2010年5月6日 9:25
    2010年4月20日 8:29
  • DerMerさん 有難うございます。

    速くなりましたが、まだまだですね。

    その後、イロイロ調べていますが、DataGridViewを使用するのは止めた方が良いと考えています。

    要件としては、表形式でデータが表示でき、行・列・セルが単一、連続範囲、スクロールを伴う連続範囲で選択可能で、その位置を教えてくれるインタフェースがあれば良いので、現在、ListView(Virtual Mode)で実装を検討しています。

    ほかの良い方法があればご教示お願いします。

    • 回答の候補に設定 山本春海 2010年4月28日 9:54
    • 回答としてマーク 山本春海 2010年5月6日 9:25
    2010年4月22日 7:03

すべての返信

  • DataGridViewのプロパティで、

    CellBorderStyleの属性を none にしたら、どうですか?

     

    セルの境界線が無くなったら、パフォーマンスはずいぶん上がりますが~~

    • 回答の候補に設定 山本春海 2010年4月28日 9:54
    • 回答としてマーク 山本春海 2010年5月6日 9:25
    2010年4月20日 8:29
  • DerMerさん 有難うございます。

    速くなりましたが、まだまだですね。

    その後、イロイロ調べていますが、DataGridViewを使用するのは止めた方が良いと考えています。

    要件としては、表形式でデータが表示でき、行・列・セルが単一、連続範囲、スクロールを伴う連続範囲で選択可能で、その位置を教えてくれるインタフェースがあれば良いので、現在、ListView(Virtual Mode)で実装を検討しています。

    ほかの良い方法があればご教示お願いします。

    • 回答の候補に設定 山本春海 2010年4月28日 9:54
    • 回答としてマーク 山本春海 2010年5月6日 9:25
    2010年4月22日 7:03