Delphi 如何防止滚轮选择TStringGrid的最后一行?

Delphi 如何防止滚轮选择TStringGrid的最后一行?,delphi,tstringgrid,scrollwheel,Delphi,Tstringgrid,Scrollwheel,我有一个TStringGrid,其中有几行实现了某种“只读”行。更确切地说,我不允许用户单击倒数第二行。如果用户单击最后一行,则不会发生任何事情;焦点不会移动到该行的单元格 我有代码(按键),一切都很顺利但是,如果用户单击顶行,然后使用鼠标滚轮向下滚动,最终焦点将移动到倒数第二行。知道如何防止这种情况吗?好吧,您可以覆盖domouseheeldown来实现这一点 function TMyStringGrid.DoMouseWheelDown(Shift: TShiftState; Mous

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


我有代码(按键),一切都很顺利但是,如果用户单击顶行,然后使用鼠标滚轮向下滚动,最终焦点将移动到倒数第二行。知道如何防止这种情况吗?

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

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;
这样做时,您不需要任何
KeyDown
代码,也不需要覆盖
domouseheeldown
。将选定单元格更改为最后一行的所有可能机制都将被此阻止

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

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Longint;
  var CanSelect: Boolean);
begin
  CanSelect := ARow<(Sender as TStringGrid).RowCount-1;
end;
程序TForm1.StringGrid1SelectCell(发送方:ToObject;ACol,ARow:Longint;
变量CanSelect:Boolean);
开始

CanSelect:=ARow那么,您可以覆盖
domouseheeldown
来实现这一点

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;
这样做时,您不需要任何
KeyDown
代码,也不需要覆盖
domouseheeldown
。将选定单元格更改为最后一行的所有可能机制都将被此阻止

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

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Longint;
  var CanSelect: Boolean);
begin
  CanSelect := ARow<(Sender as TStringGrid).RowCount-1;
end;
程序TForm1.StringGrid1SelectCell(发送方:ToObject;ACol,ARow:Longint;
变量CanSelect:Boolean);
开始

CanSelect:=ARow我通过将其放入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;

我在MouseWheelUp事件中解决了这个问题:

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


似乎在事件(滚动)发生后(焦点离开只读单元格/行时)调用了domouseheeldown。我在密码里放了一声嘟嘟,它证实了这一点。首先,焦点设置为只读单元格,然后我再滚动一次,听到嘟嘟声。不在我的
TCustomGrid
派生类中。无论如何,请使用
SelectCell
。一切都好。一行代码可以完成所有操作。你可以全力以赴,很好<当您从TCustomGrid派生时,code>domouseheeldown
也执行所需的操作。也许在这和你的代码之间还有别的东西把事情搞砸了。不管怎样,
SelectCell
是正确的选择。@TLama和处理
KeyDown
。因此,我恭敬地建议,
SelectCell
是一条路。@TLama是的,没错。对不起,我已经习惯了我自己的网格,它是从
TCustomGrid
派生的。答案现在已更新。似乎在事件(滚动)发生后(当焦点离开只读单元格/行时)会调用domouseheeldown。我在密码里放了一声嘟嘟,它证实了这一点。首先,焦点设置为只读单元格,然后我再滚动一次,听到嘟嘟声。不在我的
TCustomGrid
派生类中。无论如何,请使用
SelectCell
。一切都好。一行代码可以完成所有操作。你可以全力以赴,很好<当您从TCustomGrid派生时,code>domouseheeldown
也执行所需的操作。也许在这和你的代码之间还有别的东西把事情搞砸了。不管怎样,
SelectCell
是正确的选择。@TLama和处理
KeyDown
。因此,我恭敬地建议,
SelectCell
是一条路。@TLama是的,没错。对不起,我已经习惯了我自己的网格,它是从
TCustomGrid
派生的。现在更新答案。要回答您的问题,请说明如何预防。。。只需修复代码,因为您描述的行为不同于没有任何事件处理的字符串网格的默认行为。当你滚动时,网格行选择会改变,但每个滚动步骤会改变一行,而不是从第一行到倒数第二行(当然,当你有3行时除外:-)@TLama-我从来没有说过它会从第一行跳到最后一行。如果用户继续滚动,它最终将到达最后一行:)好吧,那么我没有得到该部分,如果用户单击最上面一行,然后使用鼠标滚轮向下滚动,焦点将移动到倒数第二行。你知道怎么预防吗?听起来这好像发生在你身上,你想阻止这种行为。@TLama-不。。。。抱歉搞混了。我在作品中添加了“最终”。需要澄清的一点是:“倒数第二个”的意思是“倒数第二个”,而不是最后一个。你的问题是说焦点不应该移到最后一行。你是说最后一排,对吗?回答你的问题,如何防止它。。。只需修复代码,因为您描述的行为不同于没有任何事件处理的字符串网格的默认行为。当你滚动时,网格行选择会改变,但每个滚动步骤会改变一行,而不是从第一行到倒数第二行(当然,当你有3行时除外:-)@TLama-我从来没有说过它会从第一行跳到最后一行。如果用户继续滚动,它最终将到达最后一行:)好吧,那么我没有得到该部分,如果用户单击最上面一行,然后使用鼠标滚轮向下滚动,焦点将移动到倒数第二行。你知道怎么预防吗?听起来这好像发生在你身上,你想阻止这种行为。@TLama-不。。。。抱歉搞混了。我在作品中添加了“最终”。需要澄清的一点是:“倒数第二个”的意思是“倒数第二个”,而不是最后一个。你的问题是说焦点不应该移到最后一行。你是说最后一行,对吗?很抱歉,这个网站是用英语的,这样任何人都能理解答案。你能翻译一下吗?对不起,布