DataGridViewのVirtualModeサンプル

using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DataGridViewVirtualModeSample
{
    public partial class Form1 : Form
    {
        private ArrayList record_datas = new ArrayList();  //グリッド表示データ

        /// <summary>
        /// ソーター基本クラス
        /// </summary>
        public abstract class RecSorter : IComparer
        {
            /// <summary>
            /// ソートオーダー
            /// </summary>
            protected SortOrder s_order = SortOrder.None;

            /// <summary>
            /// オーダーの設定
            /// </summary>
            /// <param name="order"></param>
            public void setOrder(SortOrder order) { s_order = order; }
            /// <summary>
            /// オーダーの取得
            /// </summary>
            /// <returns></returns>
            public SortOrder getOrder(){return s_order; }

            /// <summary>
            /// ソート
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public abstract int Compare(object x, object y);
        }

        /// <summary>
        /// 文字列の比較
        /// </summary>
        public class StringRecSorter : RecSorter
        {
            private string col_name;  //列名称
            
            /// <summary>
            /// コンストラクタ
            /// </summary>
            /// <param name="colName"></param>
            public StringRecSorter(String colName) { col_name = colName; }

            /// <summary>
            /// 比較
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public override int Compare(object x, object y)
            {
                Hashtable xx = (Hashtable)x;
                Hashtable yy = (Hashtable)y;
                String x_val = (String)xx[col_name];
                String y_val = (String)yy[col_name];

                int sort_ret = x_val.CompareTo(y_val);

                if (s_order == SortOrder.Descending)
                    sort_ret = sort_ret * -1;

                return sort_ret;
            }
        }

        /// <summary>
        /// 浮動小数点列の比較
        /// </summary>
        public class DoubleRecSorter : RecSorter
        {
            private string col_name;  //列名称
            
            /// <summary>
            /// コンストラクタ
            /// </summary>
            /// <param name="colName"></param>
            public DoubleRecSorter(String colName) { col_name = colName; }

            /// <summary>
            /// 比較
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public override int Compare(object x, object y)
            {
                Hashtable xx = (Hashtable)x;
                Hashtable yy = (Hashtable)y;
                Double x_val = (Double)xx[col_name];
                Double y_val = (Double)yy[col_name];

                int sort_ret = 0;

                if (x_val > y_val)
                    sort_ret = 1;
                else if (x_val < y_val)
                    sort_ret = -1;

                if (s_order == SortOrder.Descending)
                    sort_ret = sort_ret * -1;

                return sort_ret;
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.VirtualMode = true;
            dataGridView1.RowHeadersVisible = false;
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            //
            // 外部定義ファイルにグリッド情報を定義しておくとより汎用的
            //
            DataGridViewColumn[] grid_cols = new DataGridViewColumn[3];

            grid_cols[0] = new DataGridViewTextBoxColumn();
            grid_cols[0].Name = "KindName";
            grid_cols[0].Tag = new StringRecSorter("KindName");
            grid_cols[0].ValueType = typeof(String);
            grid_cols[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;

            grid_cols[1] = new DataGridViewTextBoxColumn();
            grid_cols[1].Name = "ItemName";
            grid_cols[1].Tag = new StringRecSorter("ItemName");
            grid_cols[1].ValueType = typeof(String);
            grid_cols[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;

            grid_cols[2] = new DataGridViewTextBoxColumn();
            grid_cols[2].Name = "Price";
            grid_cols[2].Tag = new DoubleRecSorter("Price");
            grid_cols[2].ValueType = typeof(Double);
            grid_cols[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;

            dataGridView1.Columns.AddRange(grid_cols);
        }

        //登録
        private void btnAddItem_Click(object sender, EventArgs e)
        {
            Hashtable row = new Hashtable();
            row["KindName"] = cmbItemKind.SelectedItem;
            row["ItemName"] = txtItem.Text;
            row["Price"] = txtPrice.Text;
            record_datas.Add(row);

            dataGridView1.RowCount += 1;
        }

        //セル値表示
        private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            try
            {
                Hashtable row = (Hashtable)record_datas[e.RowIndex];
                String col_name = dataGridView1.Columns[e.ColumnIndex].Name;
                e.Value = row[col_name];
            }
            catch { }
        }

        //セル書式設定
        private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.RowIndex % 2 == 0)
                e.CellStyle.BackColor = Color.Aqua;
        }

        //一括登録
        private void btnAddItems_Click(object sender, EventArgs e)
        {
            Random rmd = new Random(1000);
            String[] item_names = {"こんにゃく", "鉛筆", "カッター", "ぬいぐるみ", "きつね", "あぶらあげ"};

            for (int i = 0; i < 1000; i++)
            {
                Hashtable row = new Hashtable();
                int k_no = rmd.Next(6);
                row["KindName"] = "区分_" + k_no.ToString();
                k_no = rmd.Next(6);
                row["ItemName"] = item_names[k_no] + "_" + i.ToString() ;
                row["Price"] = 100.0d * k_no + i;
                record_datas.Add(row);

                dataGridView1.RowCount += 1;
            }
        }

        //ソート
        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                RecSorter sorter = (RecSorter)dataGridView1.Columns[e.ColumnIndex].Tag;

                for (int i = 0; i < dataGridView1.ColumnCount; i++)
                    dataGridView1.Columns[i].HeaderCell.SortGlyphDirection = SortOrder.None;

                if (sorter.getOrder() == SortOrder.Descending || sorter.getOrder() == SortOrder.None)
                {
                    dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
                    sorter.setOrder(SortOrder.Ascending);
                }
                else
                {
                    dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
                    sorter.setOrder(SortOrder.Descending);
                }

                record_datas.Sort(sorter);
                dataGridView1.Columns[e.ColumnIndex].Tag = sorter;
                dataGridView1.Invalidate();
            }
        }
    }
}