I’ve just realized there is no working solution in C# on how to programatically select cells across a dataGridView.

What I needed was a quick, simple and easy solution on the next behaviour: a user clicks a cell (any kind of cell: may it be a textBox cell, a checkBox cell, a comboBox cell etc.), the cell gets selected, the user clicks another cell, both the new cell and the previous cell are selected, the user click the first cell again, only the second cell is selected.

How I’ve done this? Well, first, it’s important to keep in mind that the events occur like this: CellMouseDown, CellClick, CellContentChanged, CellMouseUp, SelectionChanged. Sure, there are so many other events as well, but it’s important that you use only the CellContentChanged and the SelectionChanged events. Moreover, be aware, that if you try using the CellClick event, you won’t get this desired behaviour :).

What’s more to add, please keep in mind that you will have the MultiSelect property set to True. It would be also nice to have the SelectionMode set to CellSelect, so you don’t need to take care of several exceptions that could occur if you select the entire row/column by clicking on the column header or row header.

So:

– first, declare a System.Collections.ArrayList arrayList = new System.Collections.ArrayList(); This is where you will save a list of all of your selected cells. Sure, it would be nice to save the SelectedCells collection of the DataGridView, but that collection is obviously read-only. Otherwise, I probably wouldn’t even have this post :P.

– second, in the SelectionChanged event, do this:

foreach (DataGridViewCell arrayElement in arrayList)
{
arrayElement.Selected = true;
}

And in the CurrentCellChanged, do the following:

if (dataGridView1.CurrentCell != null)
{
label1.Text = (dataGridView1.CurrentCell.RowIndex + 1).ToString() + ” ” + (dataGridView1.CurrentCell.ColumnIndex + 1).ToString();
if (arrayList.Contains(dataGridView1.CurrentCell))
{
arrayList.Remove(dataGridView1.CurrentCell);
dataGridView1.CurrentCell.Selected = false;
}
else
{
arrayList.Add(dataGridView1.CurrentCell);
dataGridView1.CurrentCell.Selected = true;
}
}

This is basically it. Now, there is a thing about this code. The thing is that is you click on a column header, in order to re-sort the column, you’ll have a rather strange “error”: your last selected cell will get de-selected. If you re-sort the column again, the cell will be selected again. The fault of this occurrence is due to the way the events are called. Basically, when you click the header, the CurrentCellChanged is called for a first time, since you clicked the header (so, dataGridView.CurrentCell will be null). Afterwards, the CurrentCellChanged is automatically called again, because current cell’s position is moved (so the event is called for some reason…).

There are several ways to get along with this thing; I’ll let you find your own solution, since:

  1. I for one, needed NonSortable columns
  2. I needed the column headers hidden

Alex M.

Leave a Reply

Post Navigation