Recent

Author Topic: TStringGrid.row and onclick event  (Read 5671 times)

straetch

  • Jr. Member
  • **
  • Posts: 75
TStringGrid.row and onclick event
« on: March 22, 2018, 10:09:54 am »
When I execute stringgrid1.row := 1 ,  then the onclick event of the stringgrid is automatically fired.
I want to distinguish between setting the row index somewhere in my program (to highlight the row) and an actual rowclick by a user.
How can I test the difference in the click handler?
I tried   if (Sender is TStringGrid)    in the handler, but this returns true in both cases.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: TStringGrid.row and onclick event
« Reply #1 on: March 22, 2018, 11:03:25 am »
AFAIK there is no way to distinguish the source of such clicks from the grid's OnClick handler alone since the Sender parameter does not provide that information.

You have to get the data indirectly. You could use code such as what is shown below. In a new Lazarus project drop a grid, label and button on the main form and name them as shown. Generate an OnClick handler for the button and complete the code as follows:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, Controls, Grids, StdCtrls;
  9.  
  10. type
  11.  
  12.   TForm1 = class(TForm)
  13.     SetRowTo1Button: TButton;
  14.     grid: TStringGrid;
  15.     WhoClickedTheGridLabel: TLabel;
  16.     procedure gridMouseUp(Sender: TObject; Button: TMouseButton;
  17.       Shift: TShiftState; X, Y: Integer);
  18.     procedure SetRowTo1ButtonClick(Sender: TObject);
  19.     procedure gridClick(Sender: TObject);
  20.   private
  21.     FRowClickedInCode: Boolean;
  22.     procedure UpdateClickReport;
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. procedure TForm1.gridClick(Sender: TObject);
  33. begin
  34.   UpdateClickReport;
  35.   if FRowClickedInCode then
  36.     FRowClickedInCode := False;
  37. end;
  38.  
  39. procedure TForm1.UpdateClickReport;
  40. var
  41.   i: Integer;
  42. begin
  43.   WhoClickedTheGridLabel.Caption := '...'; // to force a slight delay
  44.   for i:= 0 to 100000000 do;               // so you can distinguish
  45.   Application.ProcessMessages;             // separate user clicks
  46.  
  47.   case FRowClickedInCode of
  48.     True:  WhoClickedTheGridLabel.Caption := 'click generated via code';
  49.     False: WhoClickedTheGridLabel.Caption := 'click generated by user grid click';
  50.   end;
  51. end;
  52.  
  53. procedure TForm1.SetRowTo1ButtonClick(Sender: TObject);
  54. var
  55.   gridRowChanged: Boolean;
  56. begin
  57.   gridRowChanged := grid.Row <> 1;
  58.   FRowClickedInCode := True;
  59.   grid.Row := 1;
  60.   if not gridRowChanged then
  61.     UpdateClickReport;
  62. end;
  63.  
  64. procedure TForm1.gridMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  65. begin
  66.   UpdateClickReport;
  67. end;
  68.  
  69. end.

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: TStringGrid.row and onclick event
« Reply #2 on: March 22, 2018, 11:12:19 am »
When I execute stringgrid1.row := 1 ,  then the onclick event of the stringgrid is automatically fired.
I want to distinguish between setting the row index somewhere in my program (to highlight the row) and an actual rowclick by a user.
Code: Pascal  [Select][+][-]
  1. type
  2.   TGridWithGridState = class helper for TCustomGrid
  3.   strict private
  4.     function GetGridState: TGridState; inline;
  5.   public
  6.     property GridState: TGridState read GetGridState;
  7.   end;
  8.  
  9. function TGridWithGridState.GetGridState: TGridState;
  10. begin
  11.   Result := FGridState;
  12. end;
  13.  
  14. procedure TForm1.Button1Click(Sender: TObject);
  15. begin
  16.   StringGrid1.Row := 2;
  17. end;
  18.  
  19. procedure TForm1.StringGrid1Click(Sender: TObject);
  20. begin
  21.   if StringGrid1.GridState = gsSelecting then
  22.     Memo1.Append('Click by mouse')
  23.   else
  24.     Memo1.Append('Change by program')
  25. end;

straetch

  • Jr. Member
  • **
  • Posts: 75
Re: TStringGrid.row and onclick event
« Reply #3 on: March 23, 2018, 09:47:00 am »
Great,
Two different solutions that work: a workaround at the program code level and one that gives access to protected members of the grid.
I appreciate very much that I can rely on prompt expert help where my own skills are limited.
Many thanks.

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: TStringGrid.row and onclick event
« Reply #4 on: April 16, 2020, 02:21:28 pm »
Thank you howard en aSerge. The second solution works for me.

Itis still going on. By changing TStringgrid.row then even TStringgrid.Onclick is fired.
I'm working with Lazarus 2.08 / FPC 3.04. I don't  a bug report is created, but if it is I will create one.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

 

TinyPortal © 2005-2018