C# 在DataGridView中防止双重事件

C# 在DataGridView中防止双重事件,c#,datagridview,C#,Datagridview,我有一个问题,我不知道如何解决。我有一个DataGridView(EditMode=EditProgrammatically)。此网格有一个复选框列和一个或多个文本框列。功能如下(或至少应为): 单击复选框时,应切换该复选框 选择一行(或多行)并按空格键时,应切换复选框 我有两个事件处理程序: private void grid_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex >= 0 &

我有一个问题,我不知道如何解决。我有一个DataGridView(
EditMode=EditProgrammatically
)。此网格有一个复选框列和一个或多个文本框列。功能如下(或至少应为):

  • 单击复选框时,应切换该复选框
  • 选择一行(或多行)并按空格键时,应切换复选框
我有两个事件处理程序:

private void grid_CellClick(object sender, DataGridViewCellEventArgs e)
{
  if (e.RowIndex >= 0 && e.ColumnIndex == useColumn.Index)
  {
    if (ModifierKeys != Keys.Shift && ModifierKeys != Keys.Control)
    {
      ToggleRows(grid.SelectedRows);
    }
  }
}


private void RowSelectorForm_KeyDown(object sender, KeyEventArgs e)
{
  if (grid.Focused && e.KeyCode == Keys.Space)
  {
    ToggleRows(grid.SelectedRows);
    e.Handled = true;  // Not sure if this is needed or even does anything
    e.SuppressKeyPress = true;  // Or this for that matter...
  }
}
这几乎奏效了。问题在于按空格键时,复选框单元格处于活动状态。当文本框单元格处于活动状态时,它会正常工作。问题是,当按下空格键且复选框单元格处于活动状态时,两个事件都会被触发。这意味着它首先选择然后取消选择(或相反)。因此,复选框最终与原来一样。我怎样才能防止这种情况

我曾经考虑过使用一个标志,但不确定我能把它放在哪里,因为我真的不知道它是一个双重事件,还是仅仅是用户使用空格然后用鼠标点击。所以我想那真的不能用。我是否应该使用其他事件?是否有办法查看单元格是通过鼠标还是通过空格单击的?有没有办法在按下空格时禁用自动复选框切换?我能做什么



注意:RowSelector Form_向下键而不仅仅是grid_向下键的原因是我试图使用KeyPreview,然后在空格和栅格对焦时抑制按键。但是这个SuppressKeyPress似乎什么都没做=/也许我只是误解了它…

好吧,我本来不想这么做的,但我现在已经用定时器把它修好了。。。但是如果有人知道如何正确地做,请让我知道


当前解决方案:

private DateTime lastClick = DateTime.MinValue;
在这两个事件中:

if (DateTime.Now - lastClick > TimeSpan.FromMilliseconds(400))
{
  lastClick = DateTime.Now;
  ToggleRows(grid.SelectedRows);
}

我已经有一段时间没有使用C#,但我假设您可以在RowSelector Form#KeyDown中调用ToggleGrid之前断开grid_CellClick事件处理程序

调用后,可以重新连接事件处理程序


此外,可能有某种方法可以从一开始就阻止事件被触发。在某些API中,专门提供了某些不会触发任何事件的方法。

令人沮丧的问题是:

  • .Handled不阻止复选框更改
  • .SuppressKeyPress不会阻止复选框更改
  • 如果双击复选框,第一次单击将触发click()事件(切换复选框),第二次单击将触发DoubleClick()事件(再次切换复选框)

  • 但是,KeyDown事件在任何网格事件之前触发。也许设置一个标志来指示空格键被按下,或者如果行已被选中,则重置复选框的值。

    我使用了以下方法,似乎效果很好:

    private Keys _ClickSource = 0;
    
    private void dgv_CellClick(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
    {
        if (_ClickSource == 0 || _ClickSource != Keys.Space)
        {
            dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = ! (System.Convert.ToBoolean(dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value));
        }
    
        _ClickSource = null;
    }
    
    private void dgv_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        _ClickSource = e.KeyCode;
    }
    

    您必须检查此项,但KeyEventArgs.KeyCode提供鼠标点击左键。。。也许有用?但是当你用鼠标点击复选框时,KeyDown事件不会被触发,是吗?应该
    如果(_ClickSource==0 | | | | u ClickSource!=Keys.Space)
    已经被
    如果(_ClickSource==null | | | | | u ClickSource!=Keys.Space)
    ?Svish,使用“0”而不是空值。为了安全起见,请尝试两种方法并使用预期的值。