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

b1zrtrql  于 2022-11-17  发布在  其他
关注(0)|答案(8)|浏览(192)

我用数据库中的数据填充了一个datagridview。第一列是checkboxcolumn(从数据库中检索的此列的数据是BIT类型),我希望用户只选中一个。如果用户选择另一个,则必须取消选中第一个。
我看过很多代码,但没有一个是有效的。
我能做什么?
是一个带有SQL SERVER的Winforms C#应用程序。

bnl4lu3b

bnl4lu3b1#

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;
            }
         }
      }
   }
}
k4ymrczo

k4ymrczo2#

订阅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;
            }
        }
    }
}
ff29svar

ff29svar3#

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
n1bvdmb6

n1bvdmb64#

这里是一个稍微清理过的版本。我的复选框列是动态添加的,并且总是网格中的最后一列,但您可以理解:

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;
        }
    }
0s0u357o

0s0u357o5#

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;
            }
        }
    }
}
zaqlnxep

zaqlnxep6#

下面是我基于数据操作的答案。您需要表单中一个名为DataGridView1的数据网格视图,除此之外什么都不需要。

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);
    }
zaqlnxep

zaqlnxep7#

要处理dataGridView_CellValueChanged事件,我们必须触发dataGridView_CellContentClick事件(它没有复选框的当前状态),将调用CommitEdit。这将触发dataGridView_CellValueChanged事件,我们可以在其中编写逻辑来选中/取消选中复选框。

private void dataGridView_CellContentClick(object sender, 
    DataGridViewCellEventArgs e)
{
    dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

/// <summary>
/// This will be fired by CellContentClick event from above
/// </summary>
private void dataGridView_CellValueChanged(object sender, 
    DataGridViewCellEventArgs e)
{
   //0 is checkbox column index
   var columnIndex = 0;
    if (e.ColumnIndex == columnIndex )
   {      
      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;
            }
         }
      }
   }
}

//Bind the events in the form designer
this.dataGridView.CellContentClick += new DataGridViewCellEventHandler(this.dataGridView_CellContentClick);
this.dataGridView.CellValueChanged += new DataGridViewCellEventHandler(this.dataGridView_CellValueChanged);
6mzjoqzu

6mzjoqzu8#

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

相关问题