I've create an application which displays a DataGridView
with a series of questions.
The dgv structure consists of one string column for the question text and three bool/checkbox columns for the answers (yes, no, N/A).
Each single question is displayed on its own row.
I would like my program to only allow the user to select only Yes, only No or only N/A on each row.
I think I would need to uncheck the other checkbox options when one option is checked but I'm not too sure on how to do this.
I've setup CellValueChanged
and CellContentClick
events but I'm unsure of the code needed to achieve the desired functionality.
DataGridView is bound to a DataTable.
Code I have so far:
private void dgvQuestions_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
int columnIndex = e.ColumnIndex;
int rowIndex = e.RowIndex;
DataGridViewCheckBoxCell chkYes = dgvQuestions.Rows[rowIndex].Cells[2] as DataGridViewCheckBoxCell;
DataGridViewCheckBoxCell chkNo = dgvQuestions.Rows[rowIndex].Cells[3] as DataGridViewCheckBoxCell;
DataGridViewCheckBoxCell chkNA = dgvQuestions.Rows[rowIndex].Cells[4] as DataGridViewCheckBoxCell;
if (Convert.ToBoolean(chkYes.Value) == true)
{
}
if (Convert.ToBoolean(chkNo.Value) == true)
{
}
if (Convert.ToBoolean(chkNA.Value) == true)
{
}
}
private void dgvQuestions_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
dgvQuestions.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
It appears you have the CellContentClick
set up properly, however, if there are other columns in the grid, then, it may be beneficial if you check to make sure that the cell whose content was clicked is actually one of the check box cells. Otherwise the code may be setting the cells value unnecessarily.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) {
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
if (colName == "Yes" || colName == "No" || colName == "N/A") {
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
In the CellValueChanged
event, again the code should check for only the check box values. In addition, I would assume that at least ONE (1) of the cells MUST be checked. Example, if the “N/A” cell is originally checked, then the user “unchecks” that cell, then the row would have NO check boxes checked. This is the final check in the code such that if the user “unchecks” the “N/A” cell AND this leaves ALL check boxes “unchecked”, then, the code will “check” the “N/A” cell. Also, it is important to “turn OFF” the CellValueChanged
event before we change any of the check box values IN the CellValueChanged
event to avoid reentrant. Something like…
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (e.RowIndex >= 0 && e.ColumnIndex >= 0) {
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
bool checkValue;
dataGridView1.CellValueChanged -= new DataGridViewCellEventHandler(this.dataGridView1_CellValueChanged);
switch (colName) {
case "Yes":
checkValue = (bool)dataGridView1.Rows[e.RowIndex].Cells["Yes"].Value;
if (checkValue == true) {
dataGridView1.Rows[e.RowIndex].Cells["No"].Value = false;
dataGridView1.Rows[e.RowIndex].Cells["N/A"].Value = false;
}
else {
dataGridView1.Rows[e.RowIndex].Cells["N/A"].Value = true;
}
break;
case "No":
checkValue = (bool)dataGridView1.Rows[e.RowIndex].Cells["No"].Value;
if (checkValue == true) {
dataGridView1.Rows[e.RowIndex].Cells["Yes"].Value = false;
dataGridView1.Rows[e.RowIndex].Cells["N/A"].Value = false;
}
else {
dataGridView1.Rows[e.RowIndex].Cells["N/A"].Value = true;
}
break;
case "N/A":
checkValue = (bool)dataGridView1.Rows[e.RowIndex].Cells["N/A"].Value;
if (checkValue == true) {
dataGridView1.Rows[e.RowIndex].Cells["Yes"].Value = false;
dataGridView1.Rows[e.RowIndex].Cells["No"].Value = false;
}
else {
if ((bool)dataGridView1.Rows[e.RowIndex].Cells["Yes"].Value == false &&
(bool)dataGridView1.Rows[e.RowIndex].Cells["No"].Value == false) {
dataGridView1.Rows[e.RowIndex].Cells["N/A"].Value = true;
}
}
break;
default:
break;
}
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(this.dataGridView1_CellValueChanged);
}
Below is a simple example with the three columns “Yes”, “No” and “N/A” check box columns.
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
dataGridView1.DataSource = GetTable();
}
private DataTable GetTable() {
DataTable dt = new DataTable();
dt.Columns.Add("Yes", typeof(bool));
dt.Columns.Add("No", typeof(bool));
dt.Columns.Add("N/A", typeof(bool));
for (int i = 0; i < 10; i++) {
dt.Rows.Add(false, false, true);
}
return dt;
}
Hope this helps.