防止DataGridView中的双重事件

时间:2009-02-25 14:28:14

标签: c# datagridview

我有一个问题,我不知道如何解决。我有一个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...
  }
}

这几乎可行。问题是当您按空格并且复选框单元格处于活动状态时。当文本框单元格处于活动状态时,它就像它应该的那样工作。问题是,当您按空格并且复选框单元格处于活动状态时,两个事件都会被触发。这意味着它首先选择然后取消选择(或反之)。所以复选框最终会像他们一样。我该如何防止这种情况?

我已经考虑过使用一个标志,但不知道我可以把它放在哪里,因为我不知道它是双重事件还是只是用户使用空格然后用鼠标点击。所以我认为这不能真正使用。我应该使用不同的事件吗?有没有办法查看单元格是否被鼠标或空格点击?有没有办法在按下空格时禁用自动复选框切换?我该怎么办?


注意:RowSelectorForm_KeyDown而不仅仅是grid_KeyDown的原因是我尝试使用KeyPreview然后如果它是空格并且网格被聚焦则禁止按键。但那个SuppressKeyPress似乎并没有做任何事情= /也许我只是误解了它......

4 个答案:

答案 0 :(得分:0)

好吧,我不想这样做,但我现在用定时器修好了......但如果有人知道怎么做,请告诉我!!


目前的解决方案:

private DateTime lastClick = DateTime.MinValue;

并在两个事件中:

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

答案 1 :(得分:0)

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

通话结束后,您可以重新连接事件处理程序。

此外,可能有某种方法可以阻止事件被解雇。在某些API中,特别提供了某些不触发任何事件的方法。

答案 2 :(得分:0)

令人沮丧的问题是:

  1. .Handled不会阻止复选框的更改
  2. .SuppressKeyPress不会阻止复选框更改
  3. 如果您在复选框上使用DoubleClick,则第一次点击会触发Click()事件(切换复选框),第二次点击会触发DoubleClick()事件(再次切换复选框)。
  4. 但是,KeyDown事件在任何网格事件之前触发。也许设置一个标志来指示空格键已被按下,或者如果已经选择了该行,则重置该复选框的值。

答案 3 :(得分:0)

我使用了以下内容,似乎效果很好:

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