简体   繁体   English

在datagridview中如何使用复选框作为单选按钮?

[英]In datagridview how to use checkbox as radiobutton?

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

I have invested around 12 hours but didn't get success.我已经投入了大约 12 个小时,但没有成功。 As DataGridView don't provide radiobutton type of cell.由于DataGridView不提供单选按钮类型的单元格。 so i am trying to use checkbox cell as radio-buttion functionality.所以我试图使用复选框单元作为单选按钮功能。

ie I want to be checked only one checkbox in a column.即我只想选中一列中的一个复选框。

see image:看图片:

在此处输入图片说明

It looks very simple thing but trust me it is not as simple as we are thinking.看起来很简单的事情,但相信我,它并不像我们想象的那么简单。 before giving reply please test the code.在给出答复之前,请测试代码。

Here are my sample tested code which i have tried:这是我尝试过的示例测试代码:

code 1代码 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

code 2: tested on 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;
    }
}
    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;
     }

I know I'm late to the party, but here is code to use actual radio buttons instead of checkboxes.我知道我迟到了,但这里是使用实际单选按钮而不是复选框的代码。

Credit:信用:
Thanks to Arsalan Tamiz's blog post, on which this code is based.感谢 Arsalan Tamiz 的博客文章,此代码基于该文章。
http://arsalantamiz.blogspot.com/2008/09/using-datagridview-checkbox-column-as.html http://arsalantamiz.blogspot.com/2008/09/using-datagridview-checkbox-column-as.html
Also thanks to M. Viper's answer for laying some of the ground work.还要感谢M. Viper对奠定一些基础工作的回答

Step 1: Add a DataGridView control to your panel and add a CheckBoxColumn (I named mine grid and colRadioButton respectively).第 1 步:将 DataGridView 控件添加到您的面板并添加一个 CheckBoxColumn(我分别命名了我的gridcolRadioButton )。 I'm not sure if this matters, but the EditMode property of my DataGridView is set to EditOnEnter .我不确定这是否重要,但我的 DataGridView 的 EditMode 属性设置为EditOnEnter

Step 2: Create an event handler for the CellPainting event.步骤 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;
    }
}

Step 3: Handle the CurrentCellDirtyStateChanged event to uncheck the previous selection.第 3 步:处理 CurrentCellDirtyStateChanged 事件以取消选中之前的选择。 This is basically the same as M. Viper's answer .这与M. Viper 的回答基本相同。

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

Step 4: (Optional) Handle the CellClick event to allow the user to check the radio button by clicking anywhere in the cell rather than only directly on the radio button.第 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();
    }
}

Try This,尝试这个,

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

Changing the default behavior of a control is undesired.不希望更改控件的默认行为。 We went through this path in one of my project and results were not fruitful.我们在我的一个项目中经历了这条道路,结果并不富有成效。 CheckBox control is used for multi-selection unlike the radio button.与单选按钮不同, CheckBox控件用于多选。 I would suggest you to write a custom RadioButtonCell for the DataGridView .我建议您为DataGridView编写一个自定义RadioButtonCell

This Build a Custom RadioButton Cell and Column for the DataGridView Control article is nice place to start.这篇为 DataGridView 控件构建自定义单选按钮单元格和列的文章是一个不错的起点。

Paste this code on datagridview cellcontentclick and it will work as radio button将此代码粘贴到 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;
            }
        }

None of the answers worked for me, so:没有一个答案对我有用,所以:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM