只允许在 DataGridView 中选中一个复选框

Posted

技术标签:

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

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

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

我能做什么?

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

【问题讨论】:

最好从没有工作的列表中添加一些代码至少我们可以尝试告诉你为什么它不起作用 Datagridview forcing only one checkbox to be selected in a column 的副本 为什么不使用单选按钮?它更易于使用,对用户来说更直观。 【参考方案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 以仅允许一个复选框。

【讨论】:

以上是关于只允许在 DataGridView 中选中一个复选框的主要内容,如果未能解决你的问题,请参考以下文章

如何检查是不是在 qtablewidget 中选中了复选框?

DataGridView 和复选框自动重新选择

如何获取dataGridView选中行的列值?

matlab gui图形界面 如何针对复选框中选中的条目在画图中legend显示

怎么在datagridview中选中一行怎么写

怎么删除datagridview中选中的行啊