Предотвращение двойных событий в DataGridView - PullRequest
1 голос
/ 25 февраля 2009

У меня есть проблема, которую я не знаю, как решить. У меня есть 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 голосов
/ 13 июня 2009

Я использовал следующее, и это, казалось, работало хорошо:

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;
}
0 голосов
/ 27 февраля 2009

Прошло время с тех пор, как я работал с C #, но я предполагаю, что вы можете отключить обработчик события grid_CellClick перед вызовом ToggleGrid в RowSelectorForm_KeyDown.

После вызова вы можете повторно подключить обработчик событий.

Кроме того, может быть какой-то способ подавить событие с самого начала. В некоторых API предусмотрены определенные методы, которые не вызывают никаких событий.

0 голосов
/ 28 марта 2009

Расстраивающие проблемы:

  1. . Handled не препятствует смене флажка
  2. .SuppressKeyPress не запрещает изменение флажка
  3. Если вы дважды нажали на флажок, первый щелчок вызывает событие Click () (переключение флажка), а второй щелчок запускает событие DoubleClick () (переключение флажка еще раз).

Однако событие KeyDown срабатывает перед любым из событий сетки. Возможно, установите флажок, указывающий, что пробел был нажат, или, если строка уже была выбрана, сбросьте значение флажка.

0 голосов
/ 27 февраля 2009

Ну, я не хотел этого делать, но теперь я исправил это с помощью таймера ... но если кто-нибудь знает, как это сделать правильно, пожалуйста, дайте мне знать !!


Текущее решение:

private DateTime lastClick = DateTime.MinValue;

и в обоих случаях:

if (DateTime.Now - lastClick > TimeSpan.FromMilliseconds(400))
{
  lastClick = DateTime.Now;
  ToggleRows(grid.SelectedRows);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...