简体   繁体   中英

I need to allow user to check only one checkbox in all three columns checkboxes added in datagridview C#

I have a datagridview which i load from a datatable. i manually add three columns via DataGridViewCheckBoxCell class. Each row will be updated according to the checkbox checked by users. i am facing problem how to restrict user to select or check one checkbox from all the three available in the selected row in the loaded datagridview.

The problem would be solved if there was an option of radio button adding in datagridview column or could i add a group of 3 radiobuttons as a column for each row.

This is what my datagrid looks like after adding 3 datagridviewcheckboxCells

My code snippet of adding columns is

if (DG.DataSource != null)
                {
                    DataGridViewCheckBoxColumn ChbColReceived = new DataGridViewCheckBoxColumn();
                    DataGridViewCheckBoxColumn ChbColCancelled = new DataGridViewCheckBoxColumn();
                    DataGridViewCheckBoxColumn ChbColStop = new DataGridViewCheckBoxColumn();
                    DG.Columns.Add(ChbColReceived);
                    DG.Columns.Add(ChbColCancelled);
                    DG.Columns.Add(ChbColStop);
                    ChbColReceived.HeaderText = "Received";
                    ChbColCancelled.HeaderText = "Cancelled";
                    ChbColStop.HeaderText = "Stopped";
                }

Your suggestion will be appreciable. Regards

Solution: Thanks to all devs/Gurus who helped me out. Special thanks to @JohnG whos answer is ticked as well. I have changed it a bit that may be acceptable for the person who answered. Here is my code which have solved my problem.

private void DG_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            try
            {
                int colIndex = DG.CurrentCell.ColumnIndex;
                int rowIndex = DG.CurrentCell.RowIndex;
                bool currentValue;
                if (DG.Columns[colIndex].Index == 11 || DG.Columns[colIndex].Index == 12 || DG.Columns[colIndex].Index == 13)
                {
                    DG.CurrentCellDirtyStateChanged -= new EventHandler(DG_CurrentCellDirtyStateChanged);
                    currentValue = !(bool)DG.Rows[rowIndex].Cells[colIndex].FormattedValue;
                    switch (DG.Columns[colIndex].Index)
                    {
                        case 11:
                            if (currentValue == true)
                            {
                                DG.Rows[rowIndex].Cells[12].Value = false;
                                DG.Rows[rowIndex].Cells[13].Value = false;
                            }
                            break;
                        case 12:
                            if (currentValue == true)
                            {
                                DG.Rows[rowIndex].Cells[11].Value = false;
                                DG.Rows[rowIndex].Cells[13].Value = false;
                            }
                            break;
                        case 13:
                            if (currentValue == true)
                            {
                                DG.Rows[rowIndex].Cells[11].Value = false;
                                DG.Rows[rowIndex].Cells[12].Value = false;
                            }
                            break;
                    }
                    DG.CommitEdit(DataGridViewDataErrorContexts.Commit);
                    DG.CurrentCellDirtyStateChanged += new EventHandler(DG_CurrentCellDirtyStateChanged);
                }
            }
            catch (Exception) { throw; }
        }

The Col[11],Col[12],col[13] are my target checkboxed columns. Thanks @JohnG for your time and concern.

FYI , Radio buttons does this process by default, we use radio buttons for selecting gender. we can select any one option. you can use this default process for selecting any one of theree columns. use checkboxes as radio buttons.

check this stackoverflow solution

There are several ways to achieve this, however a brute force approach would be to wire up the grids CurrentCellDirtyStateChanged event. This event will fire BEFORE the check box has changed its value, however we can still use it to determine what the current state of the check box is. The logic goes something like…

Check to see if the cell changed is one of the check box cells. If it is, then check its value by NEGATING its current value like…

currentValue = !(bool)dataGridView1.Rows[rowIndex].Cells[colIndex].FormattedValue;

Note the “!” negation here as whatever value it currently is, it will change to the negated value when we leave this event. From here, we simply check if the new value is true , if it is, then we want to set the other check boxes to false . This can be done with a simple switch/case statement.

It should be noted that since the code is possibly “changing” the other check box values, we need to turn this event OFF BEFORE we set those values to avoid any kind of re-entrant.

Below is a simple example of what is described above. I manually added the columns/rows to the grid, however, it should still work if the grid is data bound.

在此处输入图片说明

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) {
  int colIndex = dataGridView1.CurrentCell.ColumnIndex;
  int rowIndex = dataGridView1.CurrentCell.RowIndex;
  bool currentValue;
  string status = "Pending";
  if (dataGridView1.Columns[colIndex].Name == "Received" ||
      dataGridView1.Columns[colIndex].Name == "Canceled" ||
      dataGridView1.Columns[colIndex].Name == "Stopped") {
    dataGridView1.CurrentCellDirtyStateChanged -= new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
    currentValue = !(bool)dataGridView1.Rows[rowIndex].Cells[colIndex].FormattedValue;
    switch (dataGridView1.Columns[colIndex].Name) {
      case "Received":
        if (currentValue == true) {
          dataGridView1.Rows[rowIndex].Cells["Canceled"].Value = false;
          dataGridView1.Rows[rowIndex].Cells["Stopped"].Value = false;
          status = "Received";
        }
        break;
      case "Canceled":
        if (currentValue == true) {
          dataGridView1.Rows[rowIndex].Cells["Received"].Value = false;
          dataGridView1.Rows[rowIndex].Cells["Stopped"].Value = false;
          status = "Canceled";
        }
        break;
      case "Stopped":
        if (currentValue == true) {
          dataGridView1.Rows[rowIndex].Cells["Received"].Value = false;
          dataGridView1.Rows[rowIndex].Cells["Canceled"].Value = false;
          status = "Stopped";
        }
        break;
    }
    dataGridView1.Rows[rowIndex].Cells["CurrentStatus"].Value = status;
    dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
  }
}

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