2

I'd like for the datagridview column to check all, or check none. The code below works, but is there an easier/faster way of doing this? For setting the value for all the cells in a column?

if(searchResultsGrid.Columns["checkboxColumn"].HeaderText == "CheckAll")
{
    searchResultsGrid.Columns["checkboxColumn"].HeaderText = "UncheckAll";
    foreach (DataGridViewRow row in searchResultsGrid.Rows)
    {
        row.Cells["checkboxColumn"].Value = true;
        searchResultsGrid.UpdateCellValue(0, row.Index);
    }
}
else
{
    searchResultsGrid.Columns["checkboxColumn"].HeaderText = "CheckAll";
    foreach (DataGridViewRow row in searchResultsGrid.Rows)
    {
        row.Cells["checkboxColumn"].Value = false;
        searchResultsGrid.UpdateCellValue(0, row.Index);
    }
}
Just Rudy
  • 700
  • 11
  • 28

1 Answers1

1

You could achieve this another way through some trickery. The column must be ReadOnly and the cell values Null. Clicking any cell in the column will toggle the default NullValue of the column; essentially toggling every cell.

DataGridViewCheckBoxColumn chk = new DataGridViewCheckBoxColumn(false);
chk.HeaderText = "CheckAll";
chk.Name = "checkboxColumn";
chk.ReadOnly = true;
this.dataGridView1.Columns.Add(chk);

this.dataGridView1.CellClick += DataGridView1_ToggleAll;

private void DataGridView1_ToggleAll(object sender, DataGridViewCellEventArgs e)
{
    DataGridViewCheckBoxColumn col = this.dataGridView1.Columns[e.ColumnIndex] as DataGridViewCheckBoxColumn;

    if (col?.Name == "checkboxColumn")
    {
        bool checkAll = (bool)col.DefaultCellStyle.NullValue;
        col.HeaderText = checkAll ? "CheckAll" : "UncheckAll";
        col.DefaultCellStyle.NullValue = !checkAll;
    }
}

But note: to get the checked state you'd use cell.EditedFormattedValue and not cell.Value. (Because Value of necessity would always be null for this trick to work.)


This has a creative touch to it, but you must also think about future developers. When you decide to optimize code, you must ask how it will affect maintenance. Loops are easily understood and still execute quickly. You have to weigh the worth.

Below are snippets from my findings in 100 runs each with 10,000 rows of data. These were the run times of toggling the rows:

Standard Looping

Elapsed = 00:00:00.0315538
Elapsed = 00:00:00.0107964
Elapsed = 00:00:00.0676696
Elapsed = 00:00:00.0232370
Elapsed = 00:00:00.0243285

NullValue Toggling

Elapsed = 00:00:00.0006645
Elapsed = 00:00:00.0006712
Elapsed = 00:00:00.0006804
Elapsed = 00:00:00.0007579
Elapsed = 00:00:00.0003037

Note: NullValue toggling speed was consistent despite number of rows. For small data (1000 rows), looping was 2/3rd's faster than the NullValue method.

OhBeWise
  • 5,350
  • 3
  • 32
  • 60
  • Thanks for the suggestion, but this was only an added feature; meaning that the user may opt to click each cell, or just click the header to select all. Impressive time data you have. For ~800 rows, the current process takes about 45 seconds. – Just Rudy Jul 13 '17 at 20:48
  • 1
    To be fair on the speed, my test rows only had 3 columns of simple data. Only doing this on the header cell would be easy, but it's true, this won't work for your purposes if the cell values are allowed to change from `Null`. We *might* be able to work out a solution from this point, but it would be too obscure for maintenance purposes. – OhBeWise Jul 14 '17 at 13:11