How to fix this issue with Datagridview Check Box Cell?

Asked

Viewed 1,224 times

1

I’m having a problem with the Datagridview checkbox Cell:

Click on checkbox, and it marks the Checkbox and updates a value field. I click again, and he does the opposite. Everything works normally, until I quickly click on checkbox. Then he gets lost and he doesn’t score anymore, like, the checkbox not marked on the screen, but the value is True.

I have searched other forums, I have even found answers, but none that can correct 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();
            }
        }
    }
  • Why when receiving the click you do not give an enabled false in the column and at the end of an enabled true, not allowing it to be clicked again until the specified method is executed?

  • Try using lock to prevent more than one event from changing the state at the same time.

2 answers

1


I ended up correcting this mistake in a very simple way. Even when I tested, everything is working properly.

I scheduled both events (Cellcontentclick and Cellcontentdoubleclick) to call the same function. I don’t remember because I ignored that idea before. I’ll continue with the tests, to be sure, but it stayed that way:

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();
                }
            }
    }

0

The reason he gets the wrong value when he clicks too fast is because in this case the Doubleclick event is triggered to the second click, and there is not much to do to prevent this.

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 Datagrid, the first (column 0) is of the type Checkbox and has databind for a field of type Boolean, the second (column 1) is with 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();
    }
}

This way as we are treating the change of value in the field and not the mouse click does not occur the problem

Browser other questions tagged

You are not signed in. Login or sign up in order to post.