【问题标题】:In datagridview how to use checkbox as radiobutton?在datagridview中如何使用复选框作为单选按钮?
【发布时间】:2014-04-23 16:26:09
【问题描述】:

IDE:Visual Studio c#、Winforms 应用程序。

我已经投入了大约 12 个小时,但没有获得成功。由于DataGridView 不提供单选按钮类型的单元格。所以我正在尝试使用复选框单元格作为单选按钮功能。

即我只想在一列中选中一个复选框。

看图:

这看起来很简单,但相信我,它并不像我们想象的那么简单。回复前请测试代码。

这是我尝试过的示例测试代码:

代码 1

////start
if (e.RowIndex != -1)
{
    if (dataGridView1.Rows[e.RowIndex].Cells[0].Value != null && dataGridView1.CurrentCell.ColumnIndex == 0) //null check
    {
        if (e.ColumnIndex == 0)
        {
            if (((bool)dataGridView1.Rows[e.RowIndex].Cells[0].Value == true))
            {

                for (int k = 0; k <= 4; k++)
                {
                    //uncheck all other checkboxes but keep the current as checked
                   if (k == dataGridView1.CurrentRow.Index)
                    {
                        dataGridView1.Rows[k].Cells[0].Value = false;
                 }
                    //if (gvTeam1.Rows[k].Cells[2].Selected != null)
                    //if(k !=e.RowIndex)              

                }

                // gvTeam1.Rows[e.RowIndex].Cells[2].Value = false; // keep the current captain box checked
            }
        }
        //}


        // gvTeam1.Rows[rowPointerTeam1].Cells[2].Value = true;
    }
}
//end
// here gvTeam1 is Datagridview1

代码 2: 在datagridview1上测试

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.CurrentCell.ColumnIndex == 0)
    {
        for (int i = 0; i < 8; i++)
        {
            //if (i != dataGridView1.CurrentCell.RowIndex)
                dataGridView1.Rows[i].Cells[0].Value = false;              

        }
        dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[0].Value = true;
    }
}

【问题讨论】:

标签: c# winforms checkbox datagridview


【解决方案1】:
    private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        //clean al rows
        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            row.Cells["Select"].Value = false;
        }

        //check select row
        dataGridView1.CurrentRow.Cells["Select"].Value = true;
     }

【讨论】:

  • 这允许用户检查相同的复选框两次并最终得到一个未选中的当前行(这意味着没有选中任何行)。这不是原始海报所需的单选按钮行为。无论点击多少次,如何强制当前复选框保持选中状态?
【解决方案2】:

我知道我迟到了,但这里是使用实际单选按钮而不是复选框的代码。

学分:
感谢 Arsalan Tamiz 的博客文章,此代码基于此。
http://arsalantamiz.blogspot.com/2008/09/using-datagridview-checkbox-column-as.html
还要感谢M. Viper's answer 的一些基础工作。

第 1 步: 在面板中添加一个 DataGridView 控件并添加一个 CheckBoxColumn(我分别命名为 gridcolRadioButton)。我不确定这是否重要,但我的 DataGridView 的 EditMode 属性设置为 EditOnEnter

第 2 步:为 CellPainting 事件创建一个事件处理程序。

private void grid_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.ColumnIndex == colRadioButton.Index && e.RowIndex >= 0)
    {
        e.PaintBackground(e.ClipBounds, true);

        // TODO: The radio button flickers on mouse over.
        // I tried setting DoubleBuffered on the parent panel, but the flickering persists.
        // If someone figures out how to resolve this, please leave a comment.

        Rectangle rectRadioButton = new Rectangle();
        // TODO: Would be nice to not use magic numbers here.
        rectRadioButton.Width = 14;
        rectRadioButton.Height = 14;
        rectRadioButton.X = e.CellBounds.X + (e.CellBounds.Width - rectRadioButton.Width) / 2;
        rectRadioButton.Y = e.CellBounds.Y + (e.CellBounds.Height - rectRadioButton.Height) / 2;

        ButtonState buttonState;
        if (e.Value == DBNull.Value || (bool)(e.Value) == false)
        {
            buttonState = ButtonState.Normal;
        }
        else
        {
            buttonState = ButtonState.Checked;
        }
        ControlPaint.DrawRadioButton(e.Graphics, rectRadioButton, buttonState);

        e.Paint(e.ClipBounds, DataGridViewPaintParts.Focus);

        e.Handled = true;
    }
}

第 3 步: 处理 CurrentCellDirtyStateChanged 事件以取消选中之前的选择。这个和M. Viper's answer基本一样。

private void radioButtonChanged()
{
    if (grid.CurrentCell.ColumnIndex == colRadioButton.Index)
    {
        foreach (DataGridViewRow row in grid.Rows)
        {
            // Make sure not to uncheck the radio button the user just clicked.
            if (row.Index != grid.CurrentCell.RowIndex)
            {
                row.Cells[colRadioButton.Index].Value = false;
            }
        }
    }
}

private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    radioButtonChanged();
}

第 4 步:(可选)处理 CellClick 事件以允许用户通过单击单元格中的任意位置而不是直接单击单选按钮来检查单选按钮。

private void grid_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == colRadioButton.Index)
    {
        DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)grid.Rows[e.RowIndex].Cells[colRadioButton.Index];
        cell.Value = true;
        radioButtonChanged();
    }
}

【讨论】:

    【解决方案3】:

    试试这个,

    private void dataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
    {
        UpdateCellValue(e.RowIndex);
    }
    private void UpdateCellValue(int CurrentRowIndex)
    {
        if (CurrentRowIndex < 0)
            return;
        dataGridView1.Rows[CurrentRowIndex].Cells[0].Value = true;
        dataGridView1.EndEdit();
        if (CurrentRowIndex > -1)
        {
            for (int row = 0; row < dataGridView1.Rows.Count; row++)
            {
                if (CurrentRowIndex != row)
                    dataGridView1.Rows[row].Cells[0].Value = false;
            }
        }            
    }
    

    【讨论】:

    • 不工作的人。当我离开该单元格时,此代码将取消选中所有当前复选框。
    • 现在在第 5 次单击时,我可以选中该复选框,当移动到下一列时,它再次取消选中上一个复选框。
    【解决方案4】:

    不希望更改控件的默认行为。我们在我的一个项目中经历了这条道路,结果并不富有成效。与单选按钮不同,CheckBox 控件用于多选。我建议您为DataGridView 编写自定义RadioButtonCell

    这篇Build a Custom RadioButton Cell and Column for the DataGridView Control 文章是一个不错的起点。

    【讨论】:

    • 你能提供我的dll吗?或您构建的网格的示例解决方案。
    • 你问的是哪一个? DataGridViewCheckBoxColumn 表现得像单选按钮?我没有,因为我们用 MSDN 链接中的自定义 RadioButtonCell 替换了它。
    • 好的,然后将您的自定义 RadioButtonCell 内容发送给我。 , 解决方案。您可以在 mail2friends565@gmail.com 上分享链接,您可以将 Dropbox 链接分享给我。
    【解决方案5】:

    将此代码粘贴到 datagridview cellcontentclick 上,它将用作单选按钮

            int row_index = e.RowIndex;
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                if (row_index != i)
                {
                    dataGridView1.Rows[i].Cells["Column1"].Value = false;
                }
            }
    

    【讨论】:

      【解决方案6】:

      没有一个答案对我有用,所以:

          private void MyDataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
          {
              if (e.RowIndex > -1 && myDataGridView.Columns["MyRadioButtonColumnName"].Index == e.ColumnIndex)
              {
                  int rowsCount = myDataGridView.Rows.Count - (myDataGridView.AllowUserToAddRows ? 1 : 0);
                  for (int rowIdx = 0; rowIdx < rowsCount; rowIdx++)
                  {
                      myDataGridView.Rows[rowIdx].Cells[e.ColumnIndex].Value = rowIdx == e.RowIndex;
                  }                                    
              }
          }
      
          private void MyDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
          {
              if (e.RowIndex > -1 && myDataGridView.Columns["MyRadioButtonColumnName"].Index == e.ColumnIndex)
              {
                  myDataGridView.CancelEdit();
              }
          }
      
          private void MyDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
          {
              if (e.RowIndex > -1 && myDataGridView.Columns["MyRadioButtonColumnName"].Index == e.ColumnIndex)
              {
                  bool isSelected = myDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
                  e.PaintBackground(e.ClipBounds, isSelected);
      
                  if (e.RowIndex < myDataGridView.Rows.Count - 1 || myDataGridView.AllowUserToAddRows == false)
                  {
                      bool isChecked = Convert.ToBoolean(myDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value) == true;
                      RadioButtonState state = isChecked ? RadioButtonState.CheckedNormal : RadioButtonState.UncheckedNormal; // using System.Windows.Forms.VisualStyles                        
                      RadioButtonRenderer.DrawRadioButton(e.Graphics, new Point(e.CellBounds.X + e.CellBounds.Width / 2 - 6, e.CellBounds.Y + e.CellBounds.Height / 2 - 6), state);
                  }
                  e.Handled = true;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-20
        • 2011-09-09
        • 1970-01-01
        • 1970-01-01
        • 2018-02-21
        相关资源
        最近更新 更多