2006. október 6., péntek
Sort a TListView by numerical values
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.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése