【问题标题】:Allow only one checkbox selected in DataGridView只允许在 DataGridView 中选中一个复选框
【发布时间】:2016-05-22 21:26:26
【问题描述】:

我有一个 datagridview 填充数据库中的数据。第一列是一个复选框列(从数据库中检索到的该列的数据是 BIT 类型),我希望用户只检查一个。如果用户选择了另一个,第一个必须被取消选中。

我看过很多代码,但没有一个有效。

我能做什么?

是一个带有 SQL SERVER 的 Winforms C# 应用程序。

【问题讨论】:

标签: c# sql winforms checkbox datagridview


【解决方案1】:
private void dataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
   // Whatever index is your checkbox column
   var columnIndex = 0;
   if (e.ColumnIndex == columnIndex)
   {
      // If the user checked this box, then uncheck all the other rows
      var isChecked = (bool)dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
      if (isChecked)
      {
         foreach (DataGridViewRow row in dataGridView.Rows)
         {
            if (row.Index != e.RowIndex)
            {
               row.Cells[columnIndex].Value = !isChecked;
            }
         }
      }
   }
}

【讨论】:

  • 为我工作!!谢谢!!
  • 在我的情况下不起作用,datagridview必须有一些事件参数?
  • 是的,您需要处理 CellValueChanged 事件(您可以从设计器中创建事件处理程序)
【解决方案2】:

订阅CellContentClick 并添加dataGridView.EndEdit() 以获得更好的用户体验(单元不必失去焦点以触发事件):

private void ChangeCheckedStateOfOtherCheckboxesInDgv(object sender, DataGridViewCellEventArgs e)
{
    const int chkBoxColumnIndex = 0;

    var dataGridView = (DataGridView)sender;

    if (e.ColumnIndex == chkBoxColumnIndex)
    {
        dataGridView.EndEdit();

        var isChecked = (bool)dataGridView[e.ColumnIndex, e.RowIndex].Value;

        if (isChecked)
        {
            foreach (DataGridViewRow row in dataGridView.Rows)
            {
                if (row.Index != e.RowIndex)
                    row.Cells[chkBoxColumnIndex].Value = !isChecked;
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    VB网络版

    Private Sub dataGridView_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DG_SubSyncs.CellValueChanged
        Dim columnIndex As Integer = 0
           If (e.ColumnIndex = columnIndex) Then
              'If the user checked this box, then uncheck all the other rows
              Dim isChecked As Boolean = CBool(DG_SubSyncs.Rows(e.RowIndex).Cells(e.ColumnIndex).Value)
               If (isChecked) Then
                  For Each row In DG_SubSyncs.Rows
                      If (row.Index <> e.RowIndex) Then
                          row.Cells(columnIndex).Value = Not isChecked
                         End If
                   Next
               End If
           End If
       End Sub
    

    【讨论】:

    • 但这是C#问题
    • 当然,但是我有同样的 VB dot net 问题并到达这里。我认为其他寻找 VB 答案的人也可能最终落在这里,并会欣赏 VB 等价物。
    【解决方案4】:

    这是一个稍微清理过的版本。我的复选框列是动态添加的,并且始终是网格中的最后一列,但您明白了:

        private void ProfilesGrid_CellContentClick(object sender, [NotNull] DataGridViewCellEventArgs e)
        {
            DataGridView dataGridView = (DataGridView)sender;
    
            int columnCount = dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1;
    
            if (e.ColumnIndex != columnCount)
            {
                return;
            }
    
            dataGridView.EndEdit();
    
            if (!(bool) dataGridView[e.ColumnIndex, e.RowIndex].Value)
            {
                return;
            }
    
            foreach (DataGridViewRow row in dataGridView.Rows.Cast<DataGridViewRow>().Where(row => row.Index != e.RowIndex))
            {
                row.Cells[columnCount].Value = false;
            }
        }
    

    【讨论】:

      【解决方案5】:
      private void DataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
      {
          //Check to ensure that the row CheckBox is clicked.
          if (e.RowIndex >= 0 && e.ColumnIndex == 0)
          {
              //Loop and uncheck all other CheckBoxes.
              foreach (DataGridViewRow row in dataGridView1.Rows)
              {
                  if (row.Index == e.RowIndex)
                  {
                      row.Cells["checkBoxColumn"].Value = !Convert.ToBoolean(row.Cells["checkBoxColumn"].EditedFormattedValue);
                  }
                  else
                  {
                      row.Cells["checkBoxColumn"].Value = false;
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        这是我基于数据操作的答案。 您需要在表单中命名为 DataGridView1 的 datagridview,仅此而已。

            DataTable dt;
        
            private void Form1_Load(object sender, EventArgs e)
            {
                dt = CreateDataTablePeople("People");
                
                BindingSource bs = new BindingSource();
                bs.DataSource = dt;
                dataGridView1.DataSource = bs;
        
                dt.ColumnChanging += Dt_ColumnChanging  ;
            }
        
            private void Dt_ColumnChanging(object sender, DataColumnChangeEventArgs e)
            {
                if (e.Column.ColumnName == "Abilitato")
                {
                    bool b = Convert.ToBoolean(e.ProposedValue);
                    if (!b)
                    {
                        e.ProposedValue = true;
                        return;
                    }
                    dt.ColumnChanging -= Dt_ColumnChanging;
                    for (int i = dt.Rows.Count - 1; i >= 0; i--)
                    {
                        if (dt.Rows[i]["Id"] != e.Row["Id"])
                        {
                            dt.Rows[i]["Abilitato"] = false;
                            dt.Rows[i].EndEdit();
                        }
                        
                    }
                    
                    dt.ColumnChanging += Dt_ColumnChanging;
                    
                }
            }
        
            private DataTable CreateDataTablePeople(string TableName)
            {
                using (DataTable dt = new DataTable(TableName))
                {
                    dt.Columns.Add("ID", typeof(int));
                    dt.Columns.Add("Name", typeof(string));
                    dt.Columns.Add("Abilitato", typeof(bool));
        
                    dt.LoadDataRow(new object[] { 1, "Frank", false }, true);
                    dt.LoadDataRow(new object[] { 2, "Michael", false}, true);
                    dt.LoadDataRow(new object[] { 3, "Paul", false }, true);
        
                    return dt;
                }
            }
        
            private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
            {
                DataGridViewDataErrorContexts ec = DataGridViewDataErrorContexts.Commit;
                DataGridView dg = (DataGridView)sender;
                bool b = dg.CommitEdit(ec);
            }
        

        【讨论】:

          【解决方案7】:

          您必须在 DGV 上将 VirtualMode 设置为 TRUE 以仅允许一个复选框。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-10-27
            • 1970-01-01
            • 1970-01-01
            • 2022-12-07
            • 1970-01-01
            • 2016-03-04
            • 2020-09-09
            相关资源
            最近更新 更多