Articles   Members Online: 3
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How can I sort the items in a TListView Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Sorting a TListView by the first or any arbitrary column 12-Sep-02
Category
VCL-General
Language
Delphi 3.x
Views
71
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Ernesto De Spirito

How can I sort the items in a TListView?

Answer:

Sorting by the first column

Sorting a TListView by the first column is easy:

ListView1.SortType := stText;

Setting SortType to stText is more or less like setting Sorted to True in a 
TListBox object. The list will be sorted and will remain sorted after additions and 
modifications, until SortType is set back to stNone:

ListView1.SortType := stNone;

It's like setting Sorted to False in a TListBox object. It won't undo the sorting, 
but future additions and modifications to the items list won't be sorted.

Sorting with an OnCompare event

To have a TListView sorted on another column (or arbitrary data stored or 
referenced in TListItem objects), we should either write an OnCompare event or an 
ordering function to be used with the CustomSort method. If you want to sort keep a 
list sorted while adding and modifying items, then you should use an OnCompare 
event.
1   
2   procedure(Sender: TObject; Item1, Item2: TListItem;
3     Data: Integer; var Compare: Integer) of object;


The parameter Compare which is passed by reference should be set to 1, -1 or 0 
depending on whether the first item is greater than (or should be placed after) the 
second item, the first item is lower than (or should be placed before) the second 
item, or if the two items are equal, respectively. In the following example we are 
sorting a TListView by its fourth column (wich represents integer values) in 
descending order:
4   
5   procedure TForm1.ListView1Compare(Sender: TObject; Item1,
6     Item2: TListItem; Data: Integer; var Compare: Integer);
7   var
8     n1, n2: integer;
9   begin
10    n1 := StrToInt(Item1.SubItems[2]);
11    n2 := StrToInt(Item2.SubItems[2]);
12    if n1 > n2 then
13      Compare := -1
14    else if n1 < n2 then
15      Compare := 1
16    else
17      Compare := 0;
18  end;


Now that we have an OnCompare event, to sort the list and having sorted, we should 
set SortType to stBoth (instead of stText, that sorts by the first column without 
using the OnCompare event):

ListView1.SortType := stBoth;

If you just want to perform a temporal sort, you can do the following:
19  
20  ListView1.SortType := stBoth;
21  ListView1.SortType := stNone;
22  
23  //or else:
24  
25  ListView1.CustomSort(nil, 0);


Sorting with an ordering function

If you need a faster sort, then you should write an ordering function. This 
function should return 1, -1 or 0 (like the Compare parameter of the OnCompare 
event discussed above). For example:
26  
27  function ByFourth(Item1, Item2: TListItem; Data: integer):
28    integer; stdcall;
29  var
30    n1, n2: cardinal;
31  begin
32    n1 := StrToInt(Item1.SubItems[2]);
33    n2 := StrToInt(Item2.SubItems[2]);
34    if n1 > n2 then
35      Result := -1
36    else if n1 < n2 then
37      Result := 1
38    else
39      Result := 0;
40  end;


Then, every time you want to sort the list, you call CustomSort passing the address 
of the ordering function. For example:
41  
42  ListView1.CustomSort(@ByFourth, 0);


The Data parameter of the OnCompare event is 0 if the event is called automatically 
when SortType is stData or stBoth, but if it is generated because of a call to 
CustomSort, then its value is the second parameter to this method. The same happens 
with the Data parameter of the ordering function, so the Data parameter is normally
used to specify a column to sort (we didn't use it in our example to make it 
simple).

Source Example

43  var
44    Ascending: boolean;
45  
46  function SortByColumn(Item1, Item2: TListItem; Data: integer):
47    integer; stdcall;
48  // Copyright (c) 2001 Ernesto D'Spirito
49  // edspirito@latiumsoftware.com
50  // http://www.latiumsoftware.com
51  begin
52    if Data = 0 then
53      Result := AnsiCompareText(Item1.Caption, Item2.Caption)
54    else
55      Result := AnsiCompareText(Item1.SubItems[Data - 1],
56        Item2.SubItems[Data - 1]);
57    if Result < 0 then
58    begin
59      if Ascending then
60        Result := -1
61      else
62        Result := 1;
63    end
64    else if Result > 0 then
65    begin
66      if Ascending then
67        Result := 1
68      else
69        Result := -1;
70    end;
71  end;
72  
73  procedure TForm1.ListView1ColumnClick(Sender: TObject;
74    Column: TListColumn);
75  begin
76    // Toggle column Tag
77    Column.Tag := 1 - Column.Tag; // 0 -> 1  ;  1 -> 0
78    // Determine sort order based on the value of the Tag
79    Ascending := Column.Tag = 1;
80    // Perform the sort
81    TListView(Sender).CustomSort(@SortByColumn, Column.Index);
82  end;


Copyright (c) 2001 Ernesto De Spiritomailto:edspirito@latiumsoftware.com
Visit: http://www.latiumsoftware.com/delphi-newsletter.php

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC