【问题标题】:C# DataGridView (CheckBox) Cell Click Multiple CallbacksC# DataGridView (CheckBox) 单元格单击多个回调
【发布时间】:2012-08-18 16:42:41
【问题描述】:

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

我的班级中有一个 DataGridView。此数据网格视图使用 DataGridViewCheckBoxColumn,因此每个单元格都包含一个复选框。

这是其中一行的屏幕截图:

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

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 方法获取复选框值并切换它,选中->未选中或未选中->选中。)

当用户点击不是复选框的单元格中的任意位置时,只会触发一个回调,cellClicktoggleCellCheck 方法随后被调用并且复选框状态翻转。

这正是我想要的行为。

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

正在执行的两个回调导致复选框checked 状态在第一个回调之后切换,然后在第二个回调之后再次切换。最终结果当然是复选框 checked 状态没有改变。

有什么方法可以配置 DataGridView 类来阻止两个回调被触发?或者,有没有一种方法可以检测(在 cellContentClick 方法中)这是 second 回调,或者回调是通过单击复选框生成的,然后退出不调用 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);
}

谢谢!

一月

【问题讨论】:

  • 更新...我找到了一种方法来规避这种行为。这是一个主要的 hack,但它有效......我使用了一个布尔变量,它在 cellClicked 方法中设置为 true。然后,在 cellContentClick 方法中,我检查这个布尔值。如果它是真的(复选框已经改变)然后我退出该方法。否则我切换复选框状态。这不是一个优雅的解决方案,但至少它是一个有效的解决方案。 (我仍然愿意接受有关更好方法的建议!)
  • 您不应该需要单元格内容点击处理程序 - 选中复选框时会调用单元格点击。

标签: c# datagridview checkbox callback toggle


【解决方案1】:

您应该不需要单元格内容点击处理程序 - 选中复选框时会调用单元格点击。

看来您的最终目标是让网格响应被点击的单元格内容以及被点击的实际复选框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();
    }
}

1. 我建议不要进行这种 ui 修改 - DataGridView 等控件的默认行为已广泛传播且经过良好测试。更改它们通常是个坏主意。

【讨论】:

  • +1 谢谢!关于您的脚注:我认为 DataGridView 没有经过触摸屏测试!
【解决方案2】:
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;
            } 

}

【讨论】:

    猜你喜欢
    • 2012-11-01
    • 2013-06-18
    • 2011-04-29
    • 1970-01-01
    • 2021-05-22
    • 2020-12-06
    • 2020-12-20
    • 1970-01-01
    • 2012-09-27
    相关资源
    最近更新 更多