Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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#_Datagridview_Checkbox_Callback_Toggle - Fatal编程技术网

C#DataGridView(复选框)单元格单击多个回调

C#DataGridView(复选框)单元格单击多个回调,c#,datagridview,checkbox,callback,toggle,C#,Datagridview,Checkbox,Callback,Toggle,[C#,Visual Studio 2008,Windows 7 64] 我班上有一个DataGridView。此数据网格视图使用DataGridViewCheckBoxColumn,以便每个单元格都包含一个复选框 以下是其中一行的屏幕截图: 我希望能够检测用户是否选择了单元格(单元格中的某个位置,但不在复选框的顶部)。我还想在用户选中复选框时检测I。为此,我的代码必须为这两个事件设置回调: this.CellClick += cellClick; // callback when the u

[C#,Visual Studio 2008,Windows 7 64]

我班上有一个DataGridView。此数据网格视图使用DataGridViewCheckBoxColumn,以便每个单元格都包含一个复选框

以下是其中一行的屏幕截图:

我希望能够检测用户是否选择了单元格(单元格中的某个位置,但不在复选框的顶部)。我还想在用户选中复选框时检测I。为此,我的代码必须为这两个事件设置回调:

this.CellClick += cellClick; // callback when the user selects a cell
this.CellContentClick += cellContentClick; // callback when the user selects a checkbox
以下是回调方法:

    private void cellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        toggleCellCheck(e.RowIndex, e.ColumnIndex);
    }

    private void cellClick(object sender, DataGridViewCellEventArgs e)
    {
        toggleCellCheck(e.RowIndex, e.ColumnIndex);
    }

    private void toggleCellCheck(int row, int column)
    {
        bool isChecked = (bool)this[column, row].EditedFormattedValue;
        this.Rows[row].Cells[column].Value = !isChecked;
    }
(注意:正如您所看到的,toggleCellCheck方法获取复选框值并进行切换,选中->未选中或未选中->选中。)

当用户单击单元格中非复选框的任何位置时,只会触发一个回调,即cellClick。随后调用toggleCellCheck方法,复选框状态翻转

这正是我想要的行为

我遇到的问题是,当用户直接单击复选框时,两个事件都会按以下顺序触发:cellClick然后cellContentClick

执行的两个回调都会导致复选框选中状态在第一次回调后切换,然后在第二次回调后再次切换。当然,最终结果是复选框选中状态不变

是否有某种方法可以配置DataGridView类来阻止两个回调被触发?或者,是否有一种方法可以检测(在cellContentClick方法中)这是第二次回调,或者回调是通过单击复选框生成的,然后不调用toggleCellCheck直接退出

我的想法如下:

private void cellContentClick(object sender, DataGridViewCellEventArgs e)
{
    // if sender/sender child/etc. is of type checkbox then return because
    // _cellClick_ has already been called to change the checkbox checked property
    // something like the following:
    //
    // if (typeof(sender) == CheckBox) return;
    // else toggleCellCheck(e.RowIndex, e.ColumnIndex);
}
谢谢


Jan

您不需要单元格内容单击处理程序-选中复选框时将调用单元格单击

您的最终目标似乎是使网格响应正在单击的单元格内容以及实际单击的复选框1

要执行此操作,只需使用如下内容附加到单元格单击事件:

void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Columns[e.ColumnIndex].Name == "checkboxcolumn")
    {
        Console.WriteLine("Click");
        bool isChecked = (bool)dataGridView1[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
        dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = !isChecked;
        dataGridView1.EndEdit();
    }
}


一,。我建议不要进行这种ui修改——DataGridView等控件的默认行为是广泛存在的,并且经过了良好测试。更改它们通常不是个好主意。

更新。。。我找到了规避这种行为的方法。这是一个主要的黑客,但它的工作。。。我在cellClicked方法中使用一个布尔值vaiable,它被设置为true。然后,在cellContentClick方法中,我检查这个布尔值。如果为真(复选框已更改),则退出该方法。否则,我将切换复选框状态。这不是一个优雅的解决方案,但至少它是可行的。(我仍然愿意接受关于更好的方法的建议!)您不需要单元格内容单击处理程序-选中复选框时会调用单元格单击。+1谢谢!关于你的脚注:我不认为DataGridView是用触摸屏测试的!
private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    DataGridViewCheckBoxCell dgvcell = (DataGridViewCheckBoxCell)dataGridView2[e.ColumnIndex, e.RowIndex]; 
    if ( ( Convert.ToBoolean(dataGridView2[e.ColumnIndex, e.RowIndex].Value ) == true ) )
             { 
                 dgvcell.Value = CheckState.Unchecked;
                 lst_box2.Items.Add(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString());
                 lst_box1.Items.Remove(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString());
            } 
            else 
            { 
                lst_box1.Items.Add(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString());
                lst_box2.Items.Remove(dataGridView2.Rows[e.RowIndex].Cells["ItemName"].Value.ToString());
                dgvcell.Value = CheckState.Checked;
            } 

}