首页  编辑  

ListView的自定义排序

Tags: /超级猛料/VCL/ListView/   Date Created:

...sort a TListView using the CustomSort method?

{

 This example shows how to use the TListView's CustomSort method to

 sort the items in the list using a ordering function.

 This allows you to sort custom data in the correct order you want.

 When the user clicks on a column header, the ListView will be sorted

 by that column.

 If the user clicks on the same column again, the sort order will be toggled.

}

{ custom sort styles }

type

 TCustomSortStyle = (cssAlphaNum, cssNumeric, cssDateTime);

var

 { variable to hold the sort style }

 LvSortStyle: TCustomSortStyle;

 { array to hold the sort order }

 LvSortOrder: array[0..4] of Boolean; // High[LvSortOrder] = Number of Lv Columns

implementation

{$R *.DFM}

function CustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): Integer; stdcall;

var

 s1, s2: string;

 i1, i2: Integer;

 r1, r2: Boolean;

 d1, d2: TDateTime;

 { Helper functions }

 function IsValidNumber(AString : string; var AInteger : Integer): Boolean;

 var

   Code: Integer;

 begin

   Val(AString, AInteger, Code);

   Result := (Code = 0);

 end;

 function IsValidDate(AString : string; var ADateTime : TDateTime): Boolean;

 begin

   Result := True;

   try

     ADateTime := StrToDateTime(AString);

   except

     ADateTime := 0;

     Result := False;

   end;

 end;

 function CompareDates(dt1, dt2: TDateTime): Integer;

 begin

   if (dt1 > dt2) then Result := 1

   else

     if (dt1 = dt2) then Result := 0

   else

     Result := -1;

 end;

 function CompareNumeric(AInt1, AInt2: Integer): Integer;

 begin

   if AInt1 > AInt2 then Result := 1

   else

     if AInt1 = AInt2 then Result := 0

   else

     Result := -1;

 end;

begin

 Result := 0;

 if (Item1 = nil) or (Item2 = nil) then Exit;

 case SortColumn of

   -1 :

   { Compare Captions }

   begin

     s1 := Item1.Caption;

     s2 := Item2.Caption;

   end;

   else

   { Compare Subitems }

   begin

     s1 := '';

     s2 := '';

     { Check Range }

     if (SortColumn < Item1.SubItems.Count) then

       s1 := Item1.SubItems[SortColumn];

     if (SortColumn < Item2.SubItems.Count) then

       s2 := Item2.SubItems[SortColumn]

   end;

 end;

 { Sort styles }

 case LvSortStyle of

   cssAlphaNum : Result := lstrcmp(PChar(s1), PChar(s2));

   cssNumeric  : begin

                   r1 := IsValidNumber(s1, i1);

                   r2 := IsValidNumber(s2, i2);

                   Result := ord(r1 or r2);

                   if Result <> 0 then

                     Result := CompareNumeric(i1, i2);

                 end;

   cssDateTime : begin

                   r1 := IsValidDate(s1, d1);

                   r2 := IsValidDate(s2, d2);

                   Result := ord(r1 or r2);

                   if Result <> 0 then

                     Result := CompareDates(d1, d2);

                 end;

 end;

 { Sort direction }

 if LvSortOrder[SortColumn + 1] then

   Result := - Result;

end;

{ The ListView's OnColumnClick event }

procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);

begin

 { determine the sort style }

 if Column.Index = 0 then

   LvSortStyle := cssAlphaNum

 else

   LvSortStyle := cssNumeric;

 { Call the CustomSort method }

 ListView1.CustomSort(@CustomSortProc, Column.Index -1);

 { Set the sort order for the column}

 LvSortOrder[Column.Index] := not LvSortOrder[Column.Index];

end;