Filtering an DataGridView that doesn't have databinding

I had this issue a few years ago (before I knew about databindings) and found a bug post at Microsoft, saying that this is confirmed, but the issue will propably not be fixed.

However, there are a few possibilities to solve this.

  1. Insted of adding rows to the datagridview, add rows to a datatable and bind it to the datagridview.

    DataTable table = new DataTable();
    table.Columns.Add("Name", typeof(String));
    table.Columns.Add("...", typeof(String));
    
    foreach (var element in list)
       table.Rows.Add(element.Name, element.Something);
    
    dataGridView1.DataSource = table1;
    table.DefaultView.RowFilter = "Name Like '...'";
    
  2. Create a Class that inherits from BindingList and implements IBindingList. Then bind it to your DataGridView.

  3. Set DataGridView VirtualMode to true.

Method two is more complicated, because you have to add your own logic to implement the FindCore Method.

And you should look here: http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/68c8b93e-d273-4289-b2b0-0e9ea644623a


The overall performance should greatly improve if you temporarily remove the rows from the dataGridView while filtering.

  1. Create a windows forms app
  2. Drop a DataGridView and four buttons to the form
  3. Copy and paste this code (don't forget to add event handlers for the button events)

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private Stopwatch watch = new Stopwatch();
        private void Form1_Load(object sender, EventArgs e)
        {
            // populate dataGridView
            for (int i = 0; i < 10000; i++)
                dataGridView1.Rows.Add("Column", i+1, 10000 - i);
    
            for (int i = 0; i < 10000; i = i + 2)
                dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Red;
    
        }
    
        // remove filter
        private void button1_Click(object sender, EventArgs e)
        {
            watch.Reset();
            watch.Start();
    
            foreach (DataGridViewRow row in dataGridView1.Rows)
                row.Visible = true;
    
    
            watch.Stop();
            MessageBox.Show(watch.ElapsedMilliseconds.ToString());
        }
    
        // add filter (hide all odd rows)
        private void button2_Click(object sender, EventArgs e)
        {
            watch.Reset();
            watch.Start();
    
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                if (Convert.ToInt32(row.Cells[1].Value) % 2 != 0)
                    row.Visible = false;
            }
    
            watch.Stop();
            MessageBox.Show(watch.ElapsedMilliseconds.ToString());
        }
    
        // remove filter (improved)
        private void button3_Click(object sender, EventArgs e)
        {
            watch.Reset();
            watch.Start();
    
            List<DataGridViewRow> rows = new List<DataGridViewRow>();
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                rows.Add(row);
            }
    
            dataGridView1.Rows.Clear();
    
            foreach (DataGridViewRow row in rows)
                row.Visible = true;
    
            dataGridView1.Rows.AddRange(rows.ToArray());
    
            watch.Stop();
            MessageBox.Show(watch.ElapsedMilliseconds.ToString());
        }
    
        // add filer (improved)
        private void button4_Click(object sender, EventArgs e)
        {
            watch.Reset();
            watch.Start();
    
            List<DataGridViewRow> rows = new List<DataGridViewRow>();
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                rows.Add(row);
            }
    
            dataGridView1.Rows.Clear();
    
            foreach (DataGridViewRow row in rows)
            {
                if (Convert.ToInt32(row.Cells[1].Value) % 2 != 0)
                {
                    row.Visible = false;
                }
            }
    
            dataGridView1.Rows.AddRange(rows.ToArray());
    
            watch.Stop();
            MessageBox.Show(watch.ElapsedMilliseconds.ToString());
        }
    }