Recent

Author Topic: row select stringgrid  (Read 19716 times)

Hansvb

  • Hero Member
  • *****
  • Posts: 825
row select stringgrid
« on: July 09, 2014, 08:36:15 pm »
Is it possible to select a row in a stringgrid with a click on the fixed cell in front of the row?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: row select stringgrid
« Reply #1 on: July 09, 2014, 08:56:53 pm »
You need to set Options.RowSelect to True and this code
Code: [Select]
procedure TForm1.StringGrid1HeaderClick(Sender: TObject; IsColumn: Boolean; Index: Integer);
begin
  if not IsColumn then (Sender as TStringGrid).Row := Index;
end;
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Hansvb

  • Hero Member
  • *****
  • Posts: 825
Re: row select stringgrid
« Reply #2 on: July 13, 2014, 03:23:08 pm »
It works great. thans.
Is it also possible to show a Arrow or ">" in the selected fixed cell?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: row select stringgrid
« Reply #3 on: July 13, 2014, 04:17:38 pm »
You can use the OnDrawCell event both to draw text (as below), or (with a few more lines of code) to paint more sophisticated symbols such as a small triangle filled with colour:

Code: [Select]
procedure TForm1.stringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
var
  grid: TStringGrid;
begin
  grid:=Sender as TStringGrid;
  if (grid.Row = aRow) and (gdFixed in aState) then begin
    grid.Canvas.TextRect(aRect, 10, 3, '>>');
  end;
end;
« Last Edit: July 13, 2014, 07:51:11 pm by howardpc »

Hansvb

  • Hero Member
  • *****
  • Posts: 825
Re: row select stringgrid
« Reply #4 on: July 13, 2014, 09:36:47 pm »
"paint more sophisticated symbols such as a small triangle filled with colour" sounds good, but first i have to understand you're code. It puts ">>" in the fixed cell. But i leaves the ">>" in de cell when you click on the next fixed cel.

rvk

  • Hero Member
  • *****
  • Posts: 6802
Re: row select stringgrid
« Reply #5 on: July 13, 2014, 10:12:53 pm »
Yeah.. there is something strange going on there.
This only happens when you click the first column and after that another row.
(otherwise, if you only click the rows from the second column or further, the code of howardpc works).
(this seems like a bug in the underlying drawing of the cells)

As an alternative, and you don't mind filling the first column of the grid with >>, you could do it like this:
Code: [Select]
procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
var
  grid: TStringGrid;
begin
  grid:=Sender as TStringGrid;
  if (grid.Row = aRow) and (ACol=0) and (gdFixed in aState) then
    grid.Cells[0,ARow]:='>>'
  else
    grid.Cells[0,ARow]:='';
end;
You would have to find a nice character to use for the arrow.

If you want to keep using the Canvas.TextRect-method you would need to use fillrect to erase the previous arrow.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: row select stringgrid
« Reply #6 on: July 13, 2014, 11:32:06 pm »
This is a bit of a hack, but gives a better selection/deselection effect, using both OnDrawCell and OnSelection:

Code: [Select]
uses types;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
var
  grid: TStringGrid;
begin
  grid:=Sender as TStringGrid;
  if (aCol=0) and (aRow=grid.Row) then
    grid.Canvas.TextRect(aRect, 10, 3, '>>');
end;

procedure TForm1.StringGrid1Selection(Sender: TObject; aCol, aRow: Integer);
const
  lastSelRow: integer=0;
var
  grid: TStringGrid;
  r: TRect;
begin
  grid:=Sender as TStringGrid;
  r:=grid.CellRect(0,lastSelRow);
  InflateRect(r, -1, -1);
  grid.Canvas.Brush.Color:=grid.FixedColor;
  grid.Canvas.FillRect(r);
  lastSelRow:=aRow;
end;

rvk

  • Hero Member
  • *****
  • Posts: 6802
Re: row select stringgrid
« Reply #7 on: July 14, 2014, 12:30:07 am »
howardpc, that doesn't still work quite right yet.
When clicking a different row then the selected one it works. But when clicking the same row as the selected one (but not the first column but further in the row) the >> disappears.

There is definitely a bug in the TStringGrid.
Once StringGrid1HeaderClick is called... the StringGrid1DrawCell is never called again for redrawing the first column. Before StringGrid1HeaderClick is called the first column is erased properly. But after... the first column is never erased.

B.T.W. This works too (but maybe it's overkill to call .invalidate for every selectrow, but hey... it's a hack for fixing a bug ;))

Code: [Select]
procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  aRect: TRect; aState: TGridDrawState);
var
  grid: TStringGrid;
begin
  grid:=Sender as TStringGrid;
  if (grid.Row=aRow) and (gdFixed in aState) then
    grid.Canvas.TextRect(aRect, 10, 3, '>>');
end;

procedure TForm1.StringGrid1HeaderClick(Sender: TObject; IsColumn: Boolean;
  Index: Integer);
begin
  if not IsColumn then (Sender as TStringGrid).Row := Index;
end;

procedure TForm1.StringGrid1Selection(Sender: TObject; aCol, aRow: Integer);
begin
  (Sender as TStringGrid).Invalidate;
end;

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: row select stringgrid
« Reply #8 on: July 14, 2014, 08:58:46 am »
I would hesistate to call this behaviour a bug (though you may be correct).
All grids are complex controls, and TStringGrid is no exception. It selectively paints some cells (e.g. fixed cells, highlighted cells, selected cell(s), alternate rows) differently from others using internal routines, and it also exposes some event properties to enable custom painting too.
It is almost inevitable that some of these 'internal' paint effects will interfere with (i. e. overwrite) other custom paint effects in an undesired way. And it will be hard if not impossible to avoid such paint conflicts using only public/published methods, for programmers who are not familiar with the order in which the various paint effects are drawn - if indeed the order is deterministic.
It may well be that reliable custom painting of fixed cells can only be achieved by creating a descendant class that thereby has access to lower-level protected methods. However, I am not that familiar with TStringGrid internals, so it may be possible to accomplish the effect Hansvb is after using only existing public methods and properties.

 

TinyPortal © 2005-2018