Recent

Author Topic: Unselect all rows in stringgrid  (Read 1948 times)

Jonny

  • Full Member
  • ***
  • Posts: 143
Unselect all rows in stringgrid
« on: February 06, 2025, 02:55:55 pm »
This is probably really easy but I have not been able to find a solution.

How to deselect all rows in a string grid?

By clicking unused space under last row, is it possible to remove selection?

Sample minimal test project attached.

« Last Edit: February 06, 2025, 07:58:04 pm by Jonny »

dsiders

  • Hero Member
  • *****
  • Posts: 1375
Re: Unselect all rows in stringgrid
« Reply #1 on: February 06, 2025, 07:30:30 pm »
How to deselect all rows in a string grid?

TStringGrid.ClearSelections
https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tcustomgrid.clearselections.html

By clicking unused space under last row, is it possible to remove selection?

That is the default behavior. If you're talking about the focus rectangle, that's a matter of removing goDrawFocusSelected from Options if its enabled.

Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #2 on: February 06, 2025, 07:44:56 pm »
Quote from: dsiders
TStringGrid.ClearSelections

Thank you. I am currently calling that from a button. But I want to replicate it by clicking the dead space below the grid. The trouble is detecting when that area is clicked.

Quote from: dsiders
That is the default behavior. If you're talking about the focus rectangle, that's a matter of removing goDrawFocusSelected from Options if its enabled.

The issue is not the focus rectangle. I want other stuff to happen when the dead space is clicked and all the rows become inactive. I have tried StringGrid.OnMouseDown but unable to check if that is in the correct area.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #3 on: February 06, 2025, 08:02:19 pm »
I have found out how to detect a click in the dead space - use a mousedown event and check whether it is below the bottom row.

But calling ClearSelections from that procedure does not deselect any currently selected cells.

Is there another step involved? I have updated the project attachment in the first post with the new detection routine.

wp

  • Hero Member
  • *****
  • Posts: 12677
Re: Unselect all rows in stringgrid
« Reply #4 on: February 06, 2025, 08:07:39 pm »
In the MouseDown handler call Grid.MouseToGridZone(X, Y). When that returns "gzInvalid" (and you had set the OutBoundEvents property to false) you have clicked on the "dead space".

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   StringGrid1.AllowOutBoundEvents := false;
  4. end;
  5.  
  6. procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  7.   Shift: TShiftState; X, Y: Integer);
  8. var
  9.   s: String;
  10.   gz: TGridZone;
  11. begin
  12.   gz := StringGrid1.MouseToGridZone(X, Y);
  13.   case gz of
  14.     gzNormal: Caption := 'gzNormal';
  15.     gzFixedCols: caption := 'gzFixedCols';
  16.     gzFixedRows: Caption := 'gzFixedRows';
  17.     gzFixedCells: Caption := 'gzFixedCells';
  18.     gzInvalid: Caption := 'gzInvalid';
  19.   end;
  20. end;

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #5 on: February 06, 2025, 08:35:54 pm »
Fantastic, thanks @wp, MouseToGridZone is much better than my solution.

Can you tell me why ClearSelections does not work from that procedure?

CM630

  • Hero Member
  • *****
  • Posts: 1295
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Unselect all rows in stringgrid
« Reply #6 on: February 06, 2025, 08:54:17 pm »
I noticed something odd - when you start the app, cell [1;1] is already selected  :o
Maybe you should remove the focus from the stringgrid to get rid of the selection.

Unless someone offers something better:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, Controls, Grids, StdCtrls, Types;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Memo1: TMemo;
  16.     StringGrid1: TStringGrid;
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure Memo1Change(Sender: TObject);
  19.     procedure StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  20.     procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  21.   private
  22.   public
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.   Inside: boolean;
  28.  
  29. implementation
  30.  
  31. {$R *.lfm}
  32.  
  33. procedure TForm1.FormCreate(Sender: TObject);
  34. begin
  35.   StringGrid1.AllowOutboundEvents := False;
  36. end;
  37.  
  38. procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  39. begin
  40.   Memo1.Append('MOUSEDOWN');
  41.   if Y < StringGrid1.CellRect(0, StringGrid1.RowCount-1).Bottom then
  42.   begin
  43.     Inside := true;
  44.     Memo1.Append('ROW CLICKED');
  45.     StringGrid1.Options :=  StringGrid1.Options + [goAlwaysShowEditor,goAutoAddRows, goRowHighlight,goEditing,goColSpanning,goRelaxedRowSelect,goTabs];
  46.     StringGrid1.Options :=  StringGrid1.Options - [goRangeSelect];
  47.     StringGrid1.ExtendedSelect := False;
  48.     StringGrid1.Refresh;
  49.   end
  50.   else
  51.   begin
  52.     Memo1.Append('DEAD SPACE');
  53.     Memo1.Append('CLEAR SELECTIONS');
  54.     StringGrid1.ClearSelections;
  55.     Inside := False;
  56.   end;
  57. end;
  58.  
  59. procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  60. begin
  61.     if (Inside = false) then
  62.     begin
  63.       StringGrid1.Options :=  StringGrid1.Options - [goAlwaysShowEditor,goAutoAddRows, goRowHighlight,goEditing,goColSpanning,goRelaxedRowSelect,goTabs];
  64.       StringGrid1.Options :=  StringGrid1.Options + [goRangeSelect];
  65.       StringGrid1.ExtendedSelect := True;
  66.       StringGrid1.Refresh;
  67.       Memo1.SetFocus;
  68.     end;
  69. end;
  70.  
  71. procedure TForm1.Memo1Change(Sender: TObject);
  72. begin
  73.   Memo1.CaretPos := Point(0, Memo1.Lines.Count-1)
  74. end;
  75.  
  76. end.
« Last Edit: February 06, 2025, 09:21:56 pm by CM630 »
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 12677
Re: Unselect all rows in stringgrid
« Reply #7 on: February 06, 2025, 10:36:04 pm »
Can you tell me why ClearSelections does not work from that procedure?
ClearSelections refers to multiple selections which are counted to be in addition to the normally selected cell, and it just clears these additional blocks without affecting the selected cell.

In order to remove the selected cell you could set its col/row indices to -1 which is outside the grid.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   StringGrid1.Row := -1;
  4.   StringGrid1.Col := -1;
  5. end;

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #8 on: February 07, 2025, 12:58:37 am »
Quote from: wp
In order to remove the selected cell you could set its col/row indices to -1 which is outside the grid.

I had considered that but get a "Grid index out of range" error.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #9 on: February 07, 2025, 01:07:15 am »
Quote from: CM630
Unless someone offers something better:

Thanks @CM630, your code works visually, but if I add a line to display the current row, it still shows the last row selected.

Code: Pascal  [Select][+][-]
  1.       ..
  2.       Memo1.SetFocus;
  3.       Memo1.Append('ROW '+IntToStr(StringGrid1.Row)); // Add this
  4.     end;
  5. end;
  6.  

CM630

  • Hero Member
  • *****
  • Posts: 1295
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Unselect all rows in stringgrid
« Reply #10 on: February 07, 2025, 08:12:06 am »
What if you make a procedure:
Code: Pascal  [Select][+][-]
  1. procedure SetFocusSG(State: boolean);
  2.   if  (State = true) then
  3.     begin
  4.       StringGrid1.Options :=  StringGrid1.Options + [goAlwaysShowEditor,goAutoAddRows, goRowHighlight,goEditing,goColSpanning,goRelaxedRowSelect,goTabs];
  5.       StringGrid1.Options :=  StringGrid1.Options - [goRangeSelect];
  6.       StringGrid1.ExtendedSelect := False;
  7.       StringGrid1.Refresh;
  8.       StringGrid1.SetFocus; //maybe focus is already set and this line is not necessary
  9.    end
  10.   else
  11.   begin
  12.       StringGrid1.Options :=  StringGrid1.Options - [goAlwaysShowEditor,goAutoAddRows, goRowHighlight,goEditing,goColSpanning,goRelaxedRowSelect,goTabs];
  13.       StringGrid1.Options :=  StringGrid1.Options + [goRangeSelect];
  14.       StringGrid1.ExtendedSelect := True;
  15.       StringGrid1.Refresh;
  16.       Memo1.SetFocus;
  17.   end;
  18. end;
And add SetFocusSG(False); after Memo1.Append('ROW '+IntT... ? (also in StringGrid1MouseDown)
Лазар 4,0RC2 32 bit (sometimes 64 bit); FPC3,2,2

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #11 on: February 07, 2025, 10:28:34 am »
Quote from: CM630
What if you make a procedure:

Thanks again, the new procedure does work the same as the old one. But StringGrid1.Row still reports that a row is selected (I have a thread that monitors it and reacts to changes). Setting grid values to -1 as suggested by @wp would be ideal. Or storing the value elsewhere, although I would rather monitor the grid rather than a duplicate copy.

wp

  • Hero Member
  • *****
  • Posts: 12677
Re: Unselect all rows in stringgrid
« Reply #12 on: February 07, 2025, 12:02:28 pm »
I am afraid that the grid internally relies heavily on the fact that there is a selected cell. Setting the grid's Row and Col to -1 worked only in a button click and only if grid.AllowOutboundEvents is true.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #13 on: February 07, 2025, 01:10:54 pm »
Quote from: wp
I am afraid that the grid internally relies heavily on the fact that there is a selected cell. Setting the grid's Row and Col to -1 worked only in a button click and only if grid.AllowOutboundEvents is true.

Thanks for the clarification, that helps.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Unselect all rows in stringgrid
« Reply #14 on: February 08, 2025, 02:16:49 am »
Quote from: wp
I am afraid that the grid internally relies heavily on the fact that there is a selected cell. Setting the grid's Row and Col to -1 worked only in a button click and only if grid.AllowOutboundEvents is true.

If AllowOutboundEvents is true then Grid.MouseToGridZone(X, Y) never returns gzInvalid - am I still missing something?

 

TinyPortal © 2005-2018