5

I have a datagridview showing installments of a loan. I created a datagridviewcheckbox column so then I can select all the installments i want to pay for.

This is a screen of the datagrid:

enter image description here

My issue is that I need to disable the checkboxes of the paid intallments. In this case, when "Restante" (what´s left to pay) is = 0.

I read some posts where they used the paint event to not show the checkbox cell, but i didnt like that solution. I thought of hiding the checkbox cell, but i don´t know if it is possible to do that.

Thats what i tried:

foreach (DataGridViewRow row in dgv_Cuotas.Rows)
            {
                if (Convert.ToDecimal(dgv_Cuotas.Rows[row.Index].Cells[17].Value) == 0)
                {
                    dgv_Cuotas.Rows[row.Index].Cells[16].Visible = false;
                }
            }

Obviously this does not works, I get a compiler error message saying that the property is read only.

Does somebody knows how to set the checkbox cell to invisible?

Just in case, I attach the DataGridViewCheckboxColumn creation code:

DataGridViewCheckBoxColumn chbox = new DataGridViewCheckBoxColumn();
            {
                chbox.CellTemplate = new DataGridViewCheckBoxCell();
                chbox.HeaderText = "";
                chbox.Name = "Seleccionar";
                chbox.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                chbox.FlatStyle = FlatStyle.Standard;
            }
            dgv_Cuotas.Columns.Insert(16, chbox);
            dgv_Cuotas.Columns[16].DisplayIndex = 0;

EDIT:

Some considerations:

I use the cell content click event to handle the checkboxes, so readonly wont work. What I want is to hide the checkbox:

private void dgv_Cuotas_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex == -1)
            return;
        if (dgv_Cuotas.Columns[e.ColumnIndex].Name == "Seleccionar")
        {
            DataGridViewRow row = dgv_Cuotas.Rows[e.RowIndex];
            DataGridViewCheckBoxCell cellSeleccion = row.Cells["Seleccionar"] as DataGridViewCheckBoxCell;
            int n_cuota = Convert.ToInt32(dgv_Cuotas[2, dgv_Cuotas.CurrentRow.Index].Value);
            Cuota cuota_seleccionada = new Cuota();
            cuota_seleccionada = Lista_cuotas.Where(x => x.num_cuota == n_cuota).First();

            if (cellSeleccion != null && Convert.ToBoolean(cellSeleccion.Value) == true)
            {
                cellSeleccion.Value = false;
                Actualizar_cuotas_seleccionadas(false, cuota_seleccionada);
            }
            else
            {
                if (cellSeleccion != null && Convert.ToBoolean(cellSeleccion.Value) == false)
                {
                    cellSeleccion.Value = true;
                    Actualizar_cuotas_seleccionadas(true, cuota_seleccionada);
                }
            }
        }

In the other hand, I´m already using the Onpaint event. Its inherited, thats why I´m trying to avoid using it.

Andres
  • 2,729
  • 5
  • 29
  • 60

8 Answers8

8

Assign a value to the checkbox cell. Then Convert it to a TextBox with a new value. Worked for me.

dataGridView1.Rows[row.Index].Cells[16].Value = false;
dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell();
dataGridView1.Rows[row.Index].Cells[16].Value = "";
Charlie
  • 81
  • 1
  • 1
5

Yes, you can do this by Converting the DataGridViewCheckBoxCell to DataGridViewTextBoxCell

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (dataGridView1.Rows[row.Index].Cells[17].EditedFormattedValue.ToString().Length == 0) //  if (string.IsNullOrWhiteSpace(dataGridView1.Rows[row.Index].Cells[4].EditedFormattedValue.ToString()))
                break; 
            if (Convert.ToDecimal(dataGridView1.Rows[row.Index].Cells[17].EditedFormattedValue) == 0)
            {
                dataGridView1.Rows[row.Index].Cells[16].Value = null;
                dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell();

            }
            else
            {
                //dgv_Cuotas.Rows[row.Index].Cells[16] = new DataGridViewCheckBoxCell();
            }
        }
spajce
  • 7,044
  • 5
  • 29
  • 44
  • 1
    Im getting this error at runtime: the formatted value of the cell has wrong type. :/ – Andres Jan 02 '13 at 15:05
  • i updated my answer.. also try check your Formatted Value of the Cell – spajce Jan 02 '13 at 15:24
  • because you're trying to convert the a string to decimal that have no value or empty string. please try to understand :) – spajce Jan 02 '13 at 20:36
  • The column 17 always has a value, thats not the cause of the error. The issue is here: dataGridView1.Rows[row.Index].Cells[16].Value = null; dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell(); I started debuging it and detected that before that line of code, my datagridview had 18 columns, but after it, it has 19. The error must be associated with that. – Andres Jan 03 '13 at 11:16
  • Using the DataError, I´m getting the error at column 16, row 0. Display and formatting error. The formatted value of the cell has wrong type. – Andres Jan 03 '13 at 11:36
  • Column 16 is the checkbox column. – Andres Jan 03 '13 at 11:47
  • i know that. i said, try to understand.. because im pretty sure my answer is closer to solve your problem :) – spajce Jan 03 '13 at 12:14
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22139/discussion-between-andres-and-spajce) – Andres Jan 03 '13 at 17:27
4

Use the cell's ReadOnly attribute to disable any modification.

If you want to turn it to hidden, you need to override the painting code for the cells.

Osama Rizwan
  • 615
  • 1
  • 7
  • 19
Matzi
  • 13,770
  • 4
  • 33
  • 50
  • Why don't you modify the `onclick` event to do nothing if it is read only? If you want to hide it, inherit another cell from the checkboxcell, and assign a new instance of it to the place where you want it. – Matzi Jan 02 '13 at 15:38
  • How do I do that? I mean, the hiding thing. – Andres Jan 02 '13 at 16:53
3

Try to hide it and the value remains, which should prevent runtime errors.

dataGridView1.Rows[row.Index].Cells[16].Style.Padding =
new Padding(dataGridView1.Rows[row.Index].Cells[16].OwningColumn.Width, 0, 0, 0);
taygetos
  • 3,005
  • 2
  • 21
  • 29
  • Welcome to stackoverflow. Please ensure you fully explain your answer. For a question like this that is several years old, with established answers, also explain what your answer does that is different. – Simon.S.A. Dec 06 '18 at 23:42
  • 1
    it makes checkbox not visible. – ysOh Aug 07 '20 at 02:56
2

I took spajce's answer and tweaked it a bit to make it work for me.

for (var i = 0; i < datagridview1.Count; i++)
{
    if ((bool)datagridview1[0, i])
        {
            datagridview1[0, i] = new DataGridViewTextBoxCell
            {
                        Style = { ForeColor = Color.Transparent, 
                                  SelectionForeColor = Color.Transparent }
            };
        }
}

We're basically iterating through the rows and looking for a 'true' checked box. If it's checked then we're converting the box to a text box and setting its text color to Transparent so the cell looks empty. I hope this helps everyone who had this problem, I spent hours trying to find a workable answer.

Justin
  • 414
  • 4
  • 8
0

There are several ways to accomplish what you want.

For example, you can use the Readonly property of the cell to avoid the user to change the values and change the appeareance of the control to look grayed:

C# DataGridViewCheckBoxColumn Hide/Gray-Out

Community
  • 1
  • 1
Yván Ecarri
  • 1,661
  • 18
  • 39
  • Ready only is useless for me, I handle the state of the checkbox using the cell onclick event. Consecuently, to make it read only is pretty easy. What I do want, is to hide the checkbox. I read that post, but I thought there might be an easier solution. I´m already using the onpaint event and dont want to screw it with new code because it is inherited. – Andres Jan 02 '13 at 15:09
0

A simple and effective alternative is to use the chkbox ThreeState property. In code below, if my object does not have an email address, then I don't want to allow the user to tick the checkbox for sending email. To do this, the check box value is set to Unknown and read-only, which means it is displayed as "unselectable" and user cannot modify.

chk = DirectCast(row.Cells(m_idxEmailChecked), DataGridViewCheckBoxCell)
If String.IsNullOrEmpty(contact.EmailAddress) Then
  chk.Value = enumTristate.Unknown
  chk.ReadOnly = True
Else
  chk.ThreeState = False
End If

Note this also requires several associated ThreeState properties to be set on the checkbox.

        .ValueType = GetType(enumTristate)
        .TrueValue = enumTristate.True
        .FalseValue = enumTristate.False
        .IndeterminateValue = enumTristate.Unknown
        .ThreeState = True

Good luck.

user3085342
  • 86
  • 1
  • 6
-1

I tried Charlie's way:

dataGridView1.Rows[row.Index].Cells[16].Value = false;
dataGridView1.Rows[row.Index].Cells[16] = new DataGridViewTextBoxCell();
dataGridView1.Rows[row.Index].Cells[16].Value = "";

I got fewer errors, but still kept getting them. So I tried to instantiate the new DataGridViewTextBoxCell separately, and that did the trick for me (I didn't need to set the checkbox cell value either):

DataGridViewTextBoxCell c = new DataGridViewTextBoxCell();
c.Value = "";
dataGridView1.Rows[row.Index].Cells[16] = c;

Hope that helps someone!