在datagridview中如何使用checkbox作为radiobutton?

时间:2014-03-18 06:20:07

标签: c# winforms checkbox datagridview

IDE:Visual Studio c#,Winforms Application。

我已经投入了大约12个小时但没有取得成功。由于DataGridView不提供放射性按钮类型的细胞。所以我试图使用复选框单元作为无线电功能。

即我只想检查一列中的一个复选框。

见图片:

enter image description here

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

以下是我尝试的示例测试代码:

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

6 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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();
    }
}

答案 2 :(得分:0)

试试这个,

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

答案 3 :(得分:0)

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

这篇Build a Custom RadioButton Cell and Column for the DataGridView Control文章是开始的好地方。

答案 4 :(得分:0)

将此代码粘贴到datagridview import System.IO main = do loop [] leadingNonSpaces [] = 0 leadingNonSpaces (' ':cs) = 0 leadingNonSpaces (c:cs) = 1 + (leadingNonSpaces cs) keepNonSpaces cs = take (leadingNonSpaces cs) cs firstWord cs = keepNonSpaces cs second x = head (drop 1 x) -- evaluation loop, taking list of defined variables (var, value) tuples -- reads a statement and prints out its value loop vars = do eof <- isEOF if eof then return () else do line <- getLine if ((firstWord line) == "set") then do let tokens = (drop 1 (tokenize line)) let value = (eval vars (second tokens)) putStrLn (show value) loop (((head tokens),value):vars) else do let res = eval vars line putStrLn (show res) loop vars -- split string into space-separated tokens, but counting -- a parenthesized subexpression as a single token tokenize [] = [] tokenize (' ':cs) = tokenize cs tokenize cs = let i = charsInToken cs in (take i cs):(tokenize (drop i cs)) -- returns # characters in first token; counts parenthesized -- expression as a single token charsInToken str = helper str 0 -- helper takes string and number of open parentheses to be matched -- returns number of chars in first token where helper [] 0 = 0 helper (' ':cs) 0 = 0 helper (' ':cs) d = 1 + (helper cs d) helper ('(':cs) d = 1 + (helper cs (d+1)) -- helper (')':cs) 1 = 1 -- correct, but unnecessary helper (')':cs) d = 1 + (helper cs (d-1)) helper (c:cs) d = 1 + (helper cs d) -- evaluates expression in its argument string, returning an int -- first argument is list of (var, value) tuples for declared variables eval vars ('(':cs) = eval vars (take ((length cs)-1) cs) eval vars (c:cs) = if (elem c "0123456789") then read (c:cs) :: Int else let ts = tokenize (c:cs) in if (elem (head (head ts)) "+-*/") then apply_op (head ts) (map (eval vars) (drop 1 ts)) else lookupVar vars (head ts) -- look up a variable in the list of (variable, value) tuples and -- return corresponding value lookupVar [] v = error ("Undefined variable: " ++ v) lookupVar ((var,val):ts) v = if(v == var) then val else lookupVar ts v -- apply an operator to a list of two integers apply_op "+" [arg1, arg2] = arg1 + arg2 apply_op "-" [arg1, arg2] = arg1 - arg2 apply_op "*" [arg1, arg2] = arg1 * arg2 apply_op "/" [arg1, arg2] = div arg1 arg2 上,它将作为单选按钮

cellcontentclick

答案 5 :(得分:0)

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

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