22

How can I make some cells in DataGridView unselectable?

By 'unselectable' I mean: It cannot be selected in any way and trying to select it won't unselect any other cell.

I don't mean ReadOnly. My cells already have this property as true.

DataGridView.MultiSelect needs to be false.

Thanks to JYL's answer I wrote a code:

    private int selectedCellRow = 0;
    private int selectedCellColumn = 0;

    private void grid_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
    {
        if (e.Cell == null || e.StateChanged != DataGridViewElementStates.Selected)
                return;

        if (e.Cell.RowIndex == 0 || e.Cell.ColumnIndex == 0 || e.Cell.RowIndex == 1 && e.Cell.ColumnIndex == 1)
        {
            e.Cell.Selected = false;
            grid.Rows[selectedCellRow].Cells[selectedCellColumn].Selected = true;
        }
        else
        {   
            selectedCellRow = e.Cell.RowIndex;
            selectedCellColumn = e.Cell.ColumnIndex;
        }

        //this was only for seeing what is happening
        //this.Text = selectedCellRow + " " + selectedCellColumn;
    }

But this leads to StackOverflow. What condition and where I need to put to prevent that?

Miko Kronn
  • 2,434
  • 10
  • 33
  • 44

3 Answers3

15

Added and commented the condition you were asking about.

private int selectedCellRow = 0;
private int selectedCellColumn = 0;

private void grid_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
{
    if (e.Cell == null || e.StateChanged != DataGridViewElementStates.Selected)
        return;

    //if Cell that changed state is to be selected you don't need to process
    //as event caused by 'unselectable' will select it again
    if (e.Cell.RowIndex == selectedCellRow && e.Cell.ColumnIndex == selectedCellColumn)
        return;

    //this condition is necessary if you want to reset your DataGridView
    if (!e.Cell.Selected)
        return;

    if (e.Cell.RowIndex == 0 || e.Cell.ColumnIndex == 0 || e.Cell.RowIndex == 1 && e.Cell.ColumnIndex == 1)
    {
        e.Cell.Selected = false;
        grid.Rows[selectedCellRow].Cells[selectedCellColumn].Selected = true;
    }
    else
    {
        selectedCellRow = e.Cell.RowIndex;
        selectedCellColumn = e.Cell.ColumnIndex;
    }       
}
Ichibann
  • 4,371
  • 9
  • 32
  • 39
  • 1
    Slight improvement might be to refer to the calling DataGridView via `e.Cell.DataGridView` and not using `grid`. Either way the event will require some "outside help" via the selected column and row indexes. Nice solution. – Derek W Sep 15 '14 at 14:06
6

You can use the event "CellStateChanged".

private void DataGridViewXYZ_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
{
                if (e.Cell == null
                    || e.StateChanged != DataGridViewElementStates.Selected)
                    return;
                if (! [condition here : can this cell be selectable ?])
                    e.Cell.Selected = false;
}

EDIT : if you leave the MultiSelect property of gridView to True, you can manage yourself a "single select" gridview with unselectable cells : il the cell is selectable, clear the other selection...

JYL
  • 8,228
  • 5
  • 39
  • 63
  • I think this would prevent cell from being selected but won't prevent previous cell from unselect. – Miko Kronn Dec 16 '10 at 13:38
  • With multiselect to true you have no problem with my code... because Multiselect to true won't deselect a cell when you clic on another one. EDIT : your general condition is present in my sample... – JYL Dec 16 '10 at 13:52
  • It works fine except it still unselects 'selectable' cell after clicking on 'unselectable' one – Miko Kronn Dec 16 '10 at 14:06
  • Do you have an unfortunate "datagridview.ClearSelection()" somewhere ? – JYL Dec 16 '10 at 14:21
  • A "hack" to this solution could be to keep the currently selected cell stored as a variable and then reselect if the clicked cell isn't supposed to be changed. Not really elegant but it should work. – Gage Dec 16 '10 at 14:24
1

I believe this article may prove useful to you:

http://blog.spencen.com/2009/04/25/readonly-rows-and-cells-in-a-datagrid.aspx

The ReadOnly property can be applied to the entire grid, a column, a row, or an individual cell.

THE DOCTOR
  • 4,399
  • 10
  • 43
  • 64