How to fix this problem with the DataGridView Check Box cell?

1

I'm having a problem with the DataGridView checkBox cell:

Click the checkBox , and it marks the Checkbox and updates a value field. I click again, and it does the opposite. Everything works fine until I quickly click on the checkBox . is not marked on the screen, but the value is set to True.

I looked in other forums, until I found answers, but none that corrects this problem.

Here is the code:

private void dgvServico_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == 0)
        {

            DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)dgvServico.CurrentRow.Cells["Check"];
            if (chk.Value == chk.TrueValue)
            {
                //chk.Value = CheckState.Unchecked;
                chk.Value = chk.FalseValue;
                valor -= Convert.ToDouble(dgvServico.CurrentRow.Cells["valorDataGridViewTextBoxColumn"].Value);
                txtValorTotal.Text = valor.ToString();
                dgvServico.Refresh();

            }
            else
            {
                //chk.Value = CheckState.Checked;
                chk.Value = chk.TrueValue;
                valor += Convert.ToDouble(dgvServico.CurrentRow.Cells["valorDataGridViewTextBoxColumn"].Value);
                txtValorTotal.Text = valor.ToString();
                dgvServico.Refresh();
            }
        }
    }
    
asked by anonymous 15.07.2014 / 15:37

2 answers

1

I ended up correcting this error in a very simple way. Until when I tested it, everything is working correctly.

I programmed the two events (CellContentClick and CellContentDoubleClick) to call the same function. I do not remember because I ignored this idea before. I'm going to continue testing, to be sure, but it looks like this:

private void dgvServico_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
    {
        SelecionarLinha(e);
    }
private void dgvServico_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        SelecionarLinha(e);
    }
private void SelecionarLinha(DataGridViewCellEventArgs e)
    {
            if (e.ColumnIndex == 0)
            {
                DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)dgvServico.CurrentRow.Cells["Check"];
                if (chk.Value == chk.TrueValue)
                {
                    chk.Value = chk.FalseValue;
                    valor -= Convert.ToDouble(dgvServico.CurrentRow.Cells["valorDataGridViewTextBoxColumn"].Value);
                    txtValorTotal.Text = valor.ToString();
                    dgvServico.Refresh();

                }
                else
                {
                    chk.Value = chk.TrueValue;
                    valor += Convert.ToDouble(dgvServico.CurrentRow.Cells["valorDataGridViewTextBoxColumn"].Value);
                    txtValorTotal.Text = valor.ToString();
                    dgvServico.Refresh();
                }
            }
    }
    
16.07.2014 / 12:56
0

The reason for it getting the wrong value when you click too fast is because in this case the DoubleClick event is triggered for the second click, and you do not have much to do to prevent it.

An alternative to doing this is to use the events CurrentCellDirtyStateChanged and CellValueChanged

As an example, let's consider that you have two columns in the DataGrid, the first one (column 0) is a CheckBox type and has a databind for a field of type boolean, the second one (column 1) has the databind for a field of type double

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    //se for a coluna 0 nós precimos que o valor seja atualizado imediatamente
    //então vamos forçar o commit deste valor aqui, disparando assim o evento
    //CellValueChanged
    if (dataGridView1.CurrentCell.ColumnIndex == 0)
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange);
}

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.CurrentRow == null)
        return;
    if (e.ColumnIndex == 0)
    {
        //se é a coluna 0 que foi modificada então é só pegar os valores
        var chk = (bool)dataGridView1.CurrentRow.Cells[0].Value;
        var val = (double)dataGridView1.CurrentRow.Cells[1].Value;
        if (chk)
            valor += val;
        else
            valor -= val;
        label1.Text = valor.ToString();
    }
}

In this way we are dealing with the change of value in the field and not the click of the mouse does not occur the problem

    
15.07.2014 / 21:42