Recent

Author Topic: [SOLVED] Moving Columns of StringGrid  (Read 11704 times)

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
[SOLVED] Moving Columns of StringGrid
« on: August 11, 2012, 03:09:51 am »
Hi,

does anybody know if there is any elegant way to manage Column indexes when option goColMoving is True ? I mean when user of app. at runtime will move columns, I need to know their positions.

Example:
Column 0: Index, Column1: Name, Column2: Date etc.
User will move columns and I cannot use
Code: [Select]
Cells[x, y] nor Cols[x][y] anymore because Columns are now elsewhere.

Or do I have to manage it myself via OnColRowMoved ? (Store positions of Columns in some extra array).

Thanks
« Last Edit: August 11, 2012, 01:38:01 pm by Blaazen »
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/

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Moving Columns of StringGrid
« Reply #1 on: August 11, 2012, 08:46:55 am »
as far as I can understand you do not need to track the index you need to know the original position, how about setting the tag property to the original column index and use that instead?
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Moving Columns of StringGrid
« Reply #2 on: August 11, 2012, 11:00:25 am »
@ how about setting the tag property to the original column index and use that instead?

Yes, it works. Thanks.

I want to allow users to move columns and to change their widths and in the end save it all to ini file. On app. start load it from ini again.
It's possible but little difficult.

I still think original positions should be part of Grid itself, to allow something like:
Code: [Select]
Cells[Columns[0].OriginalIndex, y]:='ggkhd';
Because now you have to loop through all columns and search for the Tag with origi. index.
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/

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Moving Columns of StringGrid
« Reply #3 on: August 11, 2012, 11:44:52 am »
I find it a bit strange that you have to walk through all the existing columns until you find the one with the correct tag when you already now the column you are interested at is the one pointed by the cell you are on.

Sorry I can't understand it really I'll have to see some code or flowchart to be able to keep up with your reasons.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Moving Columns of StringGrid
« Reply #4 on: August 11, 2012, 12:23:24 pm »
Quote
I find it a bit strange that you have to walk through all the existing columns until you find the one with the correct tag when you already now the column you are interested at is the one pointed by the cell you are on.

OK, a little example:
Code: [Select]
const
  cColumnIndex = 0;
  cColumnName = 1;
  cColumnDate = 2;

...
//now fill grid with any data)
procedure FillStringGridRow(ARow: Integer);
with MyGrid do
  begin
    Cells[cColumnIndex, ARow]:=inttostr(Index);
    Cells[cColimnName, ARow]:=Name;
    Cells[cColumnDate, ARow]:=DateToStr(Date);
  end;

Now, when user will move columns, you are lost, this code is unusable anymore.

Let's say:

Original State:
Code: [Select]
Index, Name, Date
Indexes
0        1        2
Tags
0        1        2

After Move
Code: [Select]
Name, Date,  Index
Indexes
0        1        2
Tags
1        2        0

Now, if you will use indexes, you will fill Index to Name, Name to Date and Date to Index. Wrong.
If you will use Tags, you will fill Index to Date, Name to Index and Index to Name. Also wrong.
You have to loop through all columns and search for the index of column with tag you need (since tag is original position).
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/

bonmario

  • Sr. Member
  • ****
  • Posts: 346
Re: Moving Columns of StringGrid
« Reply #5 on: August 11, 2012, 12:40:11 pm »
I do it adding a row at StringGrid and set their height to 0. In that row, you can save the original position of each column and the user can't see it !!!

Hi Mario

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Moving Columns of StringGrid
« Reply #6 on: August 11, 2012, 12:47:22 pm »
Quote
I do it adding a row at StringGrid and set their height to 0. In that row, you can save the original position of each column and the user can't see it !!!

Thanks, but it is the same what I can get with:
Code: [Select]
"Column[i].Tag"
I also noticed that OnColRowMoved event is in fact OnBeforeColRowMoved.
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/

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Moving Columns of StringGrid
« Reply #7 on: August 11, 2012, 01:25:04 pm »
OK, a little example:
Code: [Select]
const
  cColumnIndex = 0;
  cColumnName = 1;
  cColumnDate = 2;

...
//now fill grid with any data)

procedure FillStringGridRow(ARow: Integer);
with MyGrid do
  begin
    Cells[cColumnIndex, ARow]:= inttostr(Index);
    Cells[cColimnName, ARow]:=Name;
    Cells[cColumnDate, ARow]:=DateToStr(Date);
  end;

Code: [Select]
const
  cColumnIndex = 0;
  cColumnName = 1;
  cColumnDate = 2;

...
function ColumnText(acol,aRow:integer):string;
begin
  case acol of
    cColumnIndex : Result := inttostr(Index);
    cColumnName : Result := Name;
    cColumnDate : Result := DateToStr(Date);
  else
     raise Exception.Create('Unknown Column');
  end;
end;
//now fill grid with any data)

procedure FillStringGridRow(ARow: Integer);
var
  MyGrid : TStringGrid;
begin
    For Cntr := 0 to MyGrid.ColCount -1;
      Cells[Cntr, ARow]:= ColumnText(MyGrid.Columns[Cntr].Tag, ARow);// inttostr(Index);
end;


How about this? It should minimize the running loops to one and at the same time the case statement will minimize the speed penalty.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Moving Columns of StringGrid
« Reply #8 on: August 11, 2012, 01:37:30 pm »
Thanks.

I just have another solution:
I set
Code: [Select]
Columns[i].Tag to original positions (at design time).

I add an extra array with real positions:
Code: [Select]
RealColIndex: array of Integer;

On FormCreate:
Code: [Select]
  SetLength(RealColIndex, SG.ColCount);
  for i:=0 to SG.ColCount-1 do
    RealColIndex[i]:=i;

And OnColRowMove:
Code: [Select]
procedure TFrmMain.SGColRowMoved(Sender: TObject; IsColumn: Boolean; sIndex, tIndex: Integer);
var i: Integer;
begin
  RealColIndex[SG.Columns[sIndex].Tag]:=tIndex;
  if sIndex<tIndex then
    for i:=sIndex+1 to tIndex-1 do
      RealColIndex[SG.Columns[i].Tag]:=RealColIndex[SG.Columns[i].Tag]-1
    else
    for i:=sIndex-1 downto tIndex do
      RealColIndex[SG.Columns[i].Tag]:=RealColIndex[SG.Columns[i].Tag]+1;
end;

Now I can index like this:
Code: [Select]
Cells[RealColIndex[cColumnIndex], y]:='gdffdgfdf';

I will have to solve how to save it and reload from ini file, but problem is solved for now.
Thanks.
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/

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: [SOLVED] Moving Columns of StringGrid
« Reply #9 on: August 12, 2012, 01:50:01 am »
Although this is solved, I noticed that there is no need to manualy set
Code: [Select]
Columns[i].Tag
at design time to store original positions of Columns (as I stated in my previous posts).

Reason is that Columns is collection of TGridColumn which is derived from TCollectionItem which already have public property "ID":
Code: [Select]
property ID: Integer read FID;which already stores original index.
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/

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: [SOLVED] Moving Columns of StringGrid
« Reply #10 on: August 12, 2012, 07:13:20 am »
as far as I know ID is an autoinc number that means that depending on your persistent mechanism that might change at runtime so be careful using that.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018