Sort a TListView by numerical values (Views: 28)
Problem/Question/Abstract: My TListView is populated with file names in the first column and their sizes in the second column. To sort the data in the columns I use certain code. Now I would like the second column sorted not by Ansi values, where 822 is greater than 1000, but by numerical values. The second column must behave like the first, which means that the first click sorts the values ascending and the next click sorts them descending. Can anyone help me? Answer: Start a new project, and drop a ListView on the form. Replace all of the unit's code with code listed below. Set the ListView1's OnColumnClick Event to point to the ListView1ColumnClick in the code and link the form's OnCreate to the FormCreate. Run the program. Every time you click on the "Column 2" header, the column will sort in the opposite order. Note, if you click too quick, it'll be considered a double click, and it's not set up for that. Also, if you click on Column 1's header, it'll sort alphabetically. unit Unit1; {$O-} interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls; type TForm1 = class(TForm) ListView1: TListView; procedure FormCreate(Sender: TObject); procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn); private NameSortOrder, SizeSortOrder: integer; public end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); var i: Integer; ListItem: TListItem; begin Randomize; NameSortOrder := -1; SizeSortOrder := -1; with ListView1 do begin Align := alClient; ViewStyle := vsReport; with Columns.Add do begin Caption := 'Column 1'; width := 90; end; with Columns.Add do begin Caption := 'Column 2'; width := 90; Alignment := taRightJustify; end; for i := 1 to 20 do begin ListItem := ListView1.Items.Add; with ListItem do begin caption := format('FileName %2d', [i]); SubItems.add(Format('%3.6n', [random])); end; end; end; end; function SizeCustomSort(Item1, Item2: TListItem; ParamSort: integer): integer; stdcall; var R1, R2: real; code: Integer; begin val(Item1.SubItems.Strings[0], R1, code); {ignore code} val(Item2.SubItems.Strings[0], R2, code); if R1 > R2 then result := ParamSort else if R1 < R2 then result := -ParamSort else result := 0; end; procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin if Column.Index = 1 then begin ListView1.CustomSort(@SizeCustomSort, SizeSortOrder); SizeSortOrder := SizeSortOrder * -1; {reverse the next sort order} end else begin ListView1.SortType := stText; ListView1.AlphaSort; end; end; end. |