3

为什么 Delphi StringGrid 有时会在OnClick之后调用事件OnKeyDown

调试截图:

在此处输入图像描述

我的 OnKeyDown 事件处理程序:

var
  Top: Integer;
  Bottom: Integer;
  CurrentRow: Integer;
begin
  Top := Grid.TopRow;
  Bottom := Grid.TopRow + Grid.VisibleRowCount - 1;
  if (Key = 38) then CurrentRow := Grid.Row - 1
  else if (Key = 40) then CurrentRow := Grid.Row + 1;
  
  // Disable OnClick because sometimes a 'TStringGrid.Click' is called anyway...
  // (when clicking on form top window bar and navigating)
  Grid.OnClick := nil; 
  
  if (CurrentRow < Top - 1) or (CurrentRow > Bottom + 1) then begin
     if (Key = 38) then Grid.Row := Bottom
     else if (Key = 40) then Grid.Row := Top;
  end;
  Grid.OnClick := GridClick;
end;

编辑:

It seems the 'OnClick' is not being fired when the last line is selected and pushing 'Down' or when the first line is selected and pushing 'Up'.

重现方式:

将 TStringGrid 添加到表单并填充几行。添加“OnClick”和“OnKeyDown”处理程序。这两个处理程序方法中不需要添加特定代码。在表单的字符串网格中选择一行,然后按键盘上的向上或向下箭头。

编辑2:

这不是解决方案,但为了防止在按下向上、向下、向上翻页或向下翻页后执行“OnClick”中的代码,我在“OnKeyDown”中设置了一个变量,并在“OnClick”中检查该变量。

编辑3:

更新了堆栈跟踪和重现方式。

4

1 回答 1

5

好吧,硬编码的键码并没有使至少一点透明,但是当您使用方向键(向上、向下、向左等)更改选择时,您会看到这种效果。

为什么OnClick调用事件处理程序,是因为TCustomGrid.OnKeyDown调用TCustomGrid.FocusCell,它调用Click.

究竟为什么将焦点转移到另一个单元格会建立一个点击我不知道,我们将不得不问我想象的开发人员。当通过单击而不是键盘将焦点更改为另一个单元格时,也许可以模拟默认行为。

由于您似乎自己处理方向按键,也许您可​​以考虑通过进一步忽略该键来防止这种情况发生:

  if Key in [VK_PRIOR..VK_DOWN] then
    Key := 0;
于 2013-09-27T15:21:46.837 回答