Kylix
Tips

NEW TIPS
Database (98)
Files (1187)
Forms (125)
Graphic (126)
IDE (30)
Indy (13)
Internet / LAN (146)
IntraWeb (12)
Math (84)
Misc (137)
Multimedia (56)
Objects/
ActiveX (64)

OpenTools API (14)
Printing (47)
Strings (94)
System (275)
VCL (246)

Search Tip
Top15
Add new Tip

Forum

...sort a TListView using the CustomSort method?
Author: Thomas Stutz
[ Print tip ]    

Tip Rating (16):  
     



{
  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.

  (***)

  Dieses Beispiel zeigt die Verwendung der CustomSort Methode einer TListView.
  Damit kann man z.B Zahlen korrekt (d.h nach ihrer Grösse) sortieren lassen.
  Wenn der Anwender auf den Kopf einer Spalte klickt, wird die ensprechende
  Spalte sortiert. Bei nochmaligem Klicken auf dieselbe Spalte wird die
  Sortierreihenfolge umgekehrt.

}

{ 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 : stringvar AInteger : Integer): Boolean;
  var
    
Code: Integer;
  begin
    
Val(AString, AInteger, Code);
    Result := (Code = 0);
  end;

  function IsValidDate(AString : stringvar 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 = nilor (Item2 = nilthen 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(i2, i1);
                  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

Rate this tip:

poor
very good


Copyright  Torry's Delphi Pages Torry's Delphi Pages Maintained by Simon Grossenbacher Notes? Comments? Feel free to send... Copyright 1996-2001