简体   繁体   中英

Message Box Firing Twice When Editing a CheckBox Cell in a DataGridView

I've got a DataGridView with bound data, but there is a checkbox column that is unbound that I am keeping track of myself. The EditMode is EditProgrammatically. When the user tries to Disable the checkbox, I pop a message box asking them if they are sure they want to disable it. If they choose yes, I disable it. No, I cancel the edit. When they choose yes and I change the value, the message box fires again. Anyone have any idea why this is happening?

Here is the code in question:

private void dgv1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
        if (dgv1.BeginEdit(false))
            dgv1.EndEdit();
}

private void dgv1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
   if (dgv1.Columns[e.ColumnIndex].Name == "Enabled")
   {
     DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)dgv1.Rows[e.RowIndex].Cells["Enabled"];

      if (checkCell.Value.Equals(checkCell.FalseValue))
      {
        checkCell.Value = checkCell.TrueValue;
      }
      else
      {

       DialogResult result = MessageBox.Show(this, "Are you sure you want to Disable this?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);

        if (result == DialogResult.No)
             e.Cancel = true;

        else
           checkCell.Value = checkCell.FalseValue;

      }
    }

private void dgv1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
  dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

i am not sure why this is happening, maybe you can just show the messagebox on CurrentCellDirtyStateChanged and then call the dgv1.CancelEdit() or CommitEdit() method.

i had a similar situation, where i had to execute code after a checkboxcell changed its value. You can use this code to uncheck it after it was checked. This way the value is set to true by default checkbox functionality and later you set it back to false if not confirmed. so this is kind of dirty but should work.

void dgv1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
  if (dgv1.Columns[e.ColumnIndex].Name == "Enabled")
  {
    DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)dgv1.Rows[e.RowIndex].Cells["Enabled"];
    if(!checkCell.Checked)
    {
       DialogResult result = MessageBox.Show(this, "Are you sure you want to Disable this?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
       if (result == DialogResult.No)
       {
          checkCell.Value = checkCell.TrueValue;
       }

    }       
  }
}

the CellValueChanged event is prolly fired too late (as soon as the cell focus is lost). therefore Commit your changes in CellDirtyStateChanged

void dgv1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
  if (dgv1.IsCurrentCellDirty && dgv1.CurrentCell.ColumnIndex == dgv1.Columns["Enabled"].Index) 
  {
     dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit); // raises the cellvaluechangedevent for checkboxes and comboboxes
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM