TAdvSTringGrid - SortedRowIndex.

When moving a row with ctrl+arrowkey .... SortedRowIndex does not follow the row???


Even doing a new sort - the row will have the SortedRowIndex of the row it replaced.

Is this normal behaviour?

Insert and delete row will also show some very strange sortedrowindex values.


SortedRowIndex is a snapshot after sorting. Moving, inserting, deleting rows after this is not further synchronized in SortedRowIndex.

How do I keep it sync'ed then?

I'm often faced with filling a grid from a TList<TSomething> ... and I need the ability to add, delete and update the elements by their original index.

The best way to do this is by adding the unique element ID for example in grid.Objects[col,row] associated with a cell in the row.

So you are saying that rowindex (of any kind - realrowindex, sortedrowindex or other) is of no use when I need to keep a grid in sync with a List?

If you are doing all kinds of operations like move/insert/delete ...no. If you just sort or hide/unhider row yes.

This was an unexpected answer ... 

Investigating further still reveals som disturbing behaviour regarding SortedRowIndex.



unit Unit1;


interface


uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, AdvUtil, Vcl.Grids, AdvObj, BaseGrid, AdvGrid, Vcl.StdCtrls;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    AdvStringGrid1: TAdvStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure AdvStringGrid1GetDisplText(Sender: TObject; ACol, ARow: Integer; var Value: string);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1: TForm1;


implementation


{$R *.dfm}


procedure TForm1.AdvStringGrid1GetDisplText(Sender: TObject; ACol, ARow: Integer; var Value: string);
begin
  if (ARow > 0) and (ACol = 2) then
    Value := IntToStr(AdvStringGrid1.SortedRowIndex(ARow));
  if (ARow > 0) and (ACol = 3) then
    Value := IntToStr(AdvStringGrid1.UnSortedRowIndex(ARow));
  if (ARow > 0) and (ACol = 4) then
    Value := IntToStr(AdvStringGrid1.RealRowIndex(ARow));
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  AdvStringGrid1.HideRow(AdvStringGrid1.RealRow);
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  AdvStringGrid1.UnHideRowsAll;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  AdvStringGrid1.SortSettings.Show := true;
  AdvStringGrid1.AutoNumberCol(0);
  AdvStringGrid1.RandomFill();
  AdvStringGrid1.Cells[0,0] := 'Init';
  AdvStringGrid1.Cells[1,0] := 'Random';
  AdvStringGrid1.Cells[2,0] := 'Sorted';
  AdvStringGrid1.Cells[3,0] := 'Unsorted';
  AdvStringGrid1.Cells[4,0] := 'Real';
end;


end.


Run and try ...

position on row 5 and press the hide row button.
Result: The row is correct hidden - and values for SortedIndex reflects this. (value is now "gone")

Now Unhide - and press header for Column 1 (Random).
Notice that SortedIndex column values match Init column - all is good.
Now Hide a row !
Result: The row is hidden - BUT SortedIndex column starts having values above 9 ????

Is this still expected behaviour?

We've applied a fix for this but the code to be used in the OnGetDisplText should be:


procedure TForm1.AdvStringGrid1GetDisplText(Sender: TObject; ACol,
  ARow: Integer; var Value: string);
begin
  if (ARow > 0) and (ACol = 2) then
    Value := IntToStr(AdvStringGrid1.SortedRowIndex(AdvStringGrid1.RealRowIndex(ARow)));
  if (ARow > 0) and (ACol = 3) then
    Value := IntToStr(AdvStringGrid1.UnSortedRowIndex(AdvStringGrid1.RealRowIndex(ARow)));
  if (ARow > 0) and (ACol = 4) then
    Value := IntToStr(AdvStringGrid1.RealRowIndex(ARow));
end;

With our fix applied, above code will work as expected.

Great to hear :-)


Will the fix be included in next update? And/or can I get it via e-mail?

A source update is available upon email request