Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DataGridView-如何使复选框充当单选按钮?_C#_Winforms_Datagridview - Fatal编程技术网

C# DataGridView-如何使复选框充当单选按钮?

C# DataGridView-如何使复选框充当单选按钮?,c#,winforms,datagridview,C#,Winforms,Datagridview,我有一个Windows窗体应用程序,它在一个窗口中显示对象列表 此控件将布尔值呈现为复选框 对象属性中有一组三个复选框,它们是互斥的。其中至多有一个是真的。因此,我希望复选框的作用类似于一组单选按钮 我想现在的人们甚至不知道为什么这些被称为单选按钮。在过去,汽车上的收音机有4个或5个按钮,按下其中任何一个按钮都会导致其他按钮全部弹出。它们是相互排斥的。“单选按钮”现在可能不是一个有用的描述,因为我认为收音机不再有这样的按钮了 我怎么做?我想如果我将“CheckedChanged”事件附加到复选框

我有一个Windows窗体应用程序,它在一个窗口中显示对象列表

此控件将布尔值呈现为复选框

对象属性中有一组三个复选框,它们是互斥的。其中至多有一个是真的。因此,我希望复选框的作用类似于一组单选按钮

我想现在的人们甚至不知道为什么这些被称为单选按钮。在过去,汽车上的收音机有4个或5个按钮,按下其中任何一个按钮都会导致其他按钮全部弹出。它们是相互排斥的。“单选按钮”现在可能不是一个有用的描述,因为我认为收音机不再有这样的按钮了

我怎么做?我想如果我将“CheckedChanged”事件附加到复选框中,并且我知道该行,我将能够找到所有其他复选框


在首次呈现checkbox控件时,我可以钩住哪个事件来抓取它,以便将CheckedChanged事件附加到它?我知道关于
DataGridView.CellFormatting
,但我认为这是错误的,因为每次DataGridView绘制时都会调用它。我确实需要一个仅在第一次呈现DGV时调用的事件。

您需要的是在DGV本身上单击CellContentClick。附加一个处理程序,用于检查DGV的该列是否为复选框单元格,如果是,请取消选中该行上的所有其他复选框


不过需要注意的是,对于CheckBoxCell,此事件在复选框值实际更改之前触发。这意味着,无论对当前单元格执行什么操作,它都将被稍后触发的事件覆盖。摆脱这种情况的行为是,通过选中行上的一个复选框,然后再次选中该复选框(无论是否尝试在处理程序中设置复选框值,该复选框在第二次单击后都将被清除),可以不选中行上的任何单元格。要克服这个问题并强制选中其中一个复选框,您可以改为处理CellValueChanged,如果更改的单元格是当前单元格且未选中,请选中它。

感谢KeithS提供的有用答案

当我在文件中查找时,我发现了以下有用的信息:

DataGridView.CellValueChanged事件在提交用户指定的值时发生,通常在焦点离开单元格时发生

但是,对于复选框单元格,通常需要立即处理更改。要在单击单元格时提交更改,必须处理DataGridView.CurrentCellDirtyStateChanged事件。在处理程序中,如果当前单元格是复选框单元格,则调用DataGridView.CommittedIt方法并传入提交值

这是我用来获取无线电行为的代码:

    void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        // Manually raise the CellValueChanged event
        // by calling the CommitEdit method.
        if (dataGridView1.IsCurrentCellDirty)
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }

    public void dataGridView1_CellValueChanged(object sender,
                                               DataGridViewCellEventArgs e)
    {
        // If a check box cell is clicked, this event handler sets the value
        // of a few other checkboxes in the same row as the clicked cell.
        if (e.RowIndex < 0) return; // row is sometimes negative?
        int ix = e.ColumnIndex;
        if (ix>=1 && ix<=3)
        {
            var row = dataGridView1.Rows[e.RowIndex];

            DataGridViewCheckBoxCell checkCell =
                (DataGridViewCheckBoxCell) row.Cells[ix];

            bool isChecked = (Boolean)checkCell.Value;
            if (isChecked)
            {
                // Only turn off other checkboxes if this one is ON. 
                // It's ok for all of them to be OFF simultaneously.
                for (int i=1; i <= 3; i++)
                {
                    if (i != ix)
                    {
                        ((DataGridViewCheckBoxCell) row.Cells[i]).Value = false;
                    }
                }
            }
            dataGridView1.Invalidate();
        }
    }
void dataGridView1\u CurrentCellDirtyStateChanged(对象发送方,事件参数e)
{
//手动引发CellValueChanged事件
//通过调用committedit方法。
if(dataGridView1.IsCurrentCellDirty)
{
dataGridView1.CommittedIt(DataGridViewDataErrorContexts.Commit);
}
}
public void dataGridView1\u CellValueChanged(对象发送方,
DataGridViewCellEventArgs(e)
{
//如果单击复选框单元格,此事件处理程序将设置该值
//与单击的单元格位于同一行中的其他几个复选框。
如果(e.RowIndex<0)返回;//行有时为负数?
int ix=e.ColumnIndex;

如果(ix>=1&&ix,这里就太容易了:

Conisder您的复选框列是datagridview中的第二列

private void YourDatagridview_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
         if (IsHandleCreated)
        {
            if (YourDatagridview.CurrentCell == YourDatagridview.Rows[e.RowIndex].Cells[1])
            {
                if (Convert.ToBoolean(YourDatagridview.CurrentCell.Value) == true)
                {
                    for (int i = 0; i < YourDatagridview.RowCount; i++)
                    {
                        if (YourDatagridview.Rows[i].Cells[1] != YourDatagridview.CurrentCell)
                        {
                            YourDatagridview.Rows[i].Cells[1].Value = false;
                        }
                    }
                }
            }
        }
    }

瞧!!

非常感谢您的帖子;)“您可以处理CellValueChanged,如果更改的单元格是当前单元格且未选中,请检查它”如何防止堆栈溢出?您可以添加示例代码吗?
private void YourDatagridview_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
         if (IsHandleCreated)
        {
            if (YourDatagridview.CurrentCell == YourDatagridview.Rows[e.RowIndex].Cells[1])
            {
                if (Convert.ToBoolean(YourDatagridview.CurrentCell.Value) == true)
                {
                    for (int i = 0; i < YourDatagridview.RowCount; i++)
                    {
                        if (YourDatagridview.Rows[i].Cells[1] != YourDatagridview.CurrentCell)
                        {
                            YourDatagridview.Rows[i].Cells[1].Value = false;
                        }
                    }
                }
            }
        }
    }
private void YourDatagridview_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        if (this.YourDatagridview.IsCurrentCellDirty)
        {
            YourDatagridview.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }