0

I have a datagridview in windows form. Datagridview looks like below:

enter image description here

In this, have one Checkbox column, two textbox column.

My requirement is need to hide checkbox from the cell for the country has Germany as like below.

enter image description here

For this, I tried by two ways:

  1. By setting visible property as false.

    datagridview.Rows[rowIndex].Cells[columnIndex].visible = false;

When using visible property, it showing error like cannot assigned to readonly.

  1. Trying by converting the type of datagridview cell from checkbox to textbox for the particular cell.

    DataGridViewTextBoxCell textBoxCell = new DataGridViewTextBoxCell(); datagridview.Rows[rowIndex].Cells[columnIndex] = textBoxCell;

For this, I am getting error like "Formatted value of the cell has a wrong type".

Is anyone have idea for this?

Nivitha G
  • 243
  • 3
  • 7
  • 17
  • Does this help? https://stackoverflow.com/questions/14124033/hide-some-datagridview-checkbox-cell – A G May 11 '22 at 10:38
  • When using above mentioned solution (converting checkbox to textbox), getting error at runtime: the formatted value of the cell has wrong type. – Nivitha G May 11 '22 at 10:49
  • A good solution is usually handling `CellPaint` event and not to draw the cell content, but just background and borders. – Reza Aghaei May 11 '22 at 10:52
  • @RezaAghaei: Is have any example for "CellPaint"? – Nivitha G May 11 '22 at 11:06
  • Is there possible to achieve this by converting to textbox cell without getting this error "Formatted value of the cell has a wrong type"? – Nivitha G May 12 '22 at 08:40
  • I haven't tried other solutions, but I'd say, a generic and good way is using CellPainting event as I showed in the example; then you don't need to do it in a loop. Have you tried the example? – Reza Aghaei May 12 '22 at 10:14
  • By the way, you need to mention people by @, or put comment under their posts, otherwise they will not receive a notification for the comment. – Reza Aghaei May 12 '22 at 10:15
  • @RezaAghaei: Yes tried...Its working....Problem is that CellPainting event is calling for each cell. So it will cause performance. – Nivitha G May 12 '22 at 10:16
  • @NivithaG Don't worry about the performance on this, because it's the way that WinForms works. Even if you don't have any customization, it's raising and painting what you see on the screen. Everything that you see in a cell (no matter if it's a custom cell, or a custom painted logic or default cell) it's result of a paint. Hope you get the point. – Reza Aghaei May 12 '22 at 11:50
  • @RezaAghaei I understood. Consider we have 1000 rows and 6 columns. So, totally we have 6000 cells. Then CellPainting event will trigger 6000 times. In this case, it will cause performance. And one more thing, for my requirement I am looping the foreach loop for iterating the rows. – Nivitha G May 13 '22 at 03:27
  • No, the paint event will raise just when it’s necessary, for the cells which are in the view port. It’s the basics of Windows. I guess you didn’t get the point. Even if you have a loop, then there will be a paint for each cell. Even if you don’t have a loop, again there will be a paint for each cell. The solution that I proposed is much faster, because it just overrides the default paint and performs a custom paint. – Reza Aghaei May 13 '22 at 08:33
  • `DataGridViewCheckBoxColumn` is a standard class and does not support hiding cells. It supports `ThreeState`. Consider using it unstead of hiding cells, and save yourself from troubles. – DotNet Developer May 17 '22 at 23:50

2 Answers2

1
  1. Handle CellPainting and don't render the check box
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex == [index] && e.RowIndex == dataGridView1.NewRowIndex)
    {
        e.PaintBackground(e.ClipBounds, true);
        e.Handled = true;
    }
}
  1. Handle CellContentClick and check if the cell don't do anything. This might not be needed.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == [index] && e.RowIndex >= 0 && e.RowIndex!=dataGridView1.newRowIndex)
    {
        return false;
    }
}
A G
  • 21,087
  • 11
  • 87
  • 112
1

A good solution is handling CellPaint event and not to draw the cell content, but just background and borders:

void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    //Check if the cell is one of those in which you are interested
    if (e.ColumnIndex == 0 && e.RowIndex == 2)
    {
        //Prevent default paint
        e.Handled = true; 
        
        var selected = (e.State & DataGridViewElementStates.Selected) != 0;
        e.PaintBackground(e.CellBounds, selected);
    }
}

You may also want to prevent cell editing, by setting it as RaedOnly or handling the CellBeginEdit:

void DataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    //Check if the cell is one of those in which you are interested
    if (e.ColumnIndex == 0 && e.RowIndex == 2)
    {
        //Prevent entering to edit mode
        e.Cancel = true;
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Reza Aghaei - Thanks for your support. Cell painting is working. But for my requirement, it causes performance. – Nivitha G May 13 '22 at 10:23