【问题标题】:How do I prevent the scroll wheel from selecting the last row of a TStringGrid?如何防止滚轮选择 TStringGrid 的最后一行?
【发布时间】:2012-09-04 14:50:59
【问题描述】:

我有一个 TStringGrid 有几行,我在其中实现了某种“只读”行。更准确地说,我不允许用户单击倒数第二行。如果用户单击最后一行,则没有任何反应;焦点不会移动到该行的单元格。

我有代码(在 KeyDown 中),一切正常。 但是,如果用户点击最上面一行,然后使用鼠标滚轮向下滚动,最终焦点会移动到倒数第二行。知道如何防止这种情况吗?

【问题讨论】:

  • 回答您的问题,如何防止它...只需修复您的代码,因为您描述的行为与没有任何事件处理的字符串网格的默认行为不同。滚动时网格行选择会更改,但每个滚动步骤会更改一行,而不是从第一行到倒数第二行(当然,除非您有 3 行 :-)
  • @TLama - 我从来没有说过它会从第一行跳到最后一行。如果用户继续滚动,它最终会到达最后一行:)
  • 好吧,所以我没有得到这个部分,如果用户单击最上面一行然后使用鼠标滚轮向下滚动,焦点将移动到倒数第二行。任何想法 如何防止这种情况 听起来它正在发生在你身上,你想防止这种行为。
  • @TLama - 不......抱歉混淆。我在 OP 中添加了“最终”。
  • 澄清一点:“倒数第二个”的意思是“倒数第二个”,而不是最后一个。你的问题是说焦点不应该改变到倒数第二行。你是说最后一行吧?

标签: delphi tstringgrid scrollwheel


【解决方案1】:

好吧,您可以覆盖 DoMouseWheelDown 来实现这一点。

function TMyStringGrid.DoMouseWheelDown(Shift: TShiftState; 
  MousePos: TPoint): Boolean;
begin
  if Row<RowCount-2 then
    //only allow wheel down if we are above the penultimate row
    Result := inherited DoMouseWheelDown(Shift, MousePos)
  else
    Result := False;
end;

但是你怎么知道没有其他方法可以将焦点移到最后一行?

事实上,一个更好的解决方案是覆盖SelectCell

function TMyStringGrid.SelectCell(ACol, ARow: Longint): Boolean;
begin
  Result := ARow<RowCount-1;
end;

当您这样做时,您不需要任何KeyDown 代码,也不需要覆盖DoMouseWheelDown。将所选单元格更改为最后一行的所有可能机制都将被此阻止。

正如@TLama 正确指出的那样,您不需要子类TStringGrid 来实现这一点。您可以使用OnSelectCell 事件:

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Longint;
  var CanSelect: Boolean);
begin
  CanSelect := ARow<(Sender as TStringGrid).RowCount-1;
end;

【讨论】:

  • 似乎在事件(滚动)发生之后(当焦点离开只读单元格/行时)调用了 DoMouseWheelDown。我在代码中放了一个 BEEP,它确认了这一点。首先将焦点设置到我的只读单元格,然后我再滚动一次,我听到哔哔声。
  • 不在我的TCustomGrid 派生类中。无论如何,请使用SelectCell。它只是更好的全面。一行代码搞定一切。你可以放弃所有其他的努力。
  • 好。当您从 TCustomGrid 派生时,DoMouseWheelDown 也会执行所需的操作。也许在这和你的代码之间还有其他东西把它搞砸了。无论如何,SelectCell 是正确的选择。
  • @TLama 还要处理KeyDown。所以,我恭敬地建议SelectCell 是要走的路。
  • @TLama 是的,没错。抱歉,我已经习惯了我自己的源自TCustomGrid 的网格。答案现已更新。
【解决方案2】:

我通过将它放在事件 OnMouseWheelUp 中解决了这个问题:

procedure Tmainform.sgup(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
        sg.RowCount := sg.RowCount + 1;
        sg.RowCount := sg.RowCount - 1;
end;

【讨论】:

  • 很抱歉,本网站以英文运行,以便任何人都能理解答案。你能翻译一下吗?
猜你喜欢
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
相关资源
最近更新 更多