I have set up a form in which I have a column of checkboxes in the right column. The left columns contain data that is read-only if the corresponding checkbox column is unchecked and editable when checked. Since the data columns are dependent on each other for calculations I need (2) checked rows of the data columns editable at a time. I would like the checkable boxes to be limited to any (2) with the remaining boxes to not be checkable until at least one of the checked boxes is unchecked. I figured the best way would be to keep a running total of the number of checked boxes and somehow limit this, but I'm stuck at how to accomplish this. The code below just outputs a persistant GlobalVar.NumChecked = -1 value. Any help or direction would be appreciated.
private void dgvParameters_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgPG = dgvParameters;
if (e.RowIndex < 0) return;
GlobalVar.NumChecked = 0;
foreach (DataGridViewRow row in dgvParameters.Rows)
{
if (e.RowIndex < 0) return;
DataGridViewCheckBoxCell cell = row.Cells[5] as DataGridViewCheckBoxCell;
if (cell.Value == cell.TrueValue)
{
GlobalVar.NumChecked = 1;
break;
}
if (cell.Value != cell.TrueValue)
{
GlobalVar.NumChecked -= 1;
break;
}
}
label2.Text = Convert.ToString(GlobalVar.NumChecked); //Debug output
}
CodePudding user response:
Don't wait until the cell's Value
changes by handling the CellValueChanged
event. Handle the CurrentCellDirtyStateChanged
event instead to cancel assigning the new value (true) by calling the CancelEdit
method if you have two checked cells already.
//
using System.Linq;
// ...
private void dgvParameters_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvParameters.CurrentCell is DataGridViewCheckBoxCell &&
dgvParameters.IsCurrentCellDirty &&
!(bool)dgvParameters.CurrentCell.FormattedValue)
{
var count = dgvParameters.Rows.Cast<DataGridViewRow>()
.SelectMany(r => r.Cells.OfType<DataGridViewCheckBoxCell>()
.Where(c => (bool)c.FormattedValue))
.Count();
if (count == 2) dgvParameters.CancelEdit();
}
}
If you have more than one DataGridViewCheckBoxColumn
in the grid, then you need to specify that in the query as well.
private void dgvParameters_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
int tarCol = 2;
if (dgvParameters.CurrentCell is DataGridViewCheckBoxCell &&
dgvParameters.CurrentCell.ColumnIndex == tarCol &&
dgvParameters.IsCurrentCellDirty &&
!(bool)dgvParameters.CurrentCell.FormattedValue)
{
var count = dgvParameters.Rows.Cast<DataGridViewRow>()
.SelectMany(r => r.Cells.OfType<DataGridViewCheckBoxCell>()
.Where(c => c.ColumnIndex == tarCol)
.Where(c => (bool)c.FormattedValue))
.Count();
if (count == 2) dgvParameters.CancelEdit();
}
}