Link to home
Start Free TrialLog in
Avatar of urif
urif

asked on

sorting a listview by one of its subitems

in the program i'm writing, the listbox is sorted by the 1st column (sorttype = sText). the use has the chose to sort the list also by the 2nd column ( item.subitem(0) ).

This sort can be selected by the user. how can i sort the listview by one of its subitems?

this is not a column sort when the column is clicked. there is not column clicking in this program.

thanks
Avatar of SteveBay
SteveBay
Flag of United States of America image

Create an OnCompare event handler. Here is a simple example. This one does a compare based upon the combined string value of the first two columns
procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);
begin
     Compare := CompareText(Item1.Caption + Item1.SubItems[0],Item2.Caption + Item2.SubItems[0]);
end;
 
end;

Open in new window

You can use this events:
1. OnColumnClick: ListViewColumnClick
2. OnCompare: ListViewCompare

if user clicks on the column then listview will sort by this column.
in this events use direction of sorting also,
Direction of sorting saves into Column.Tag
first click - sort asc
second click - sort desc



uses
  Math, StrUtils; 
 
procedure TForm1.ListViewColumnClick(Sender: TObject;
  Column: TListColumn);
begin
 TListView(Sender).Tag := Column.Index;
 if Column.Tag = 0 then
  Column.Tag := 1
 else
  Column.Tag := 0;
 TListView(Sender).AlphaSort;
 if Assigned(TListView(Sender).Selected) then begin
   TListView(Sender).Selected.MakeVisible(false);
   TListView(Sender).Selected.Focused := true
 end
end;
 
function InverseValue(AValue: integer; AInverse: boolean = true): integer;
begin
 Result := AValue;
 if AInverse then
  Result := -AValue
end;
 
procedure TForm1.ListViewCompare(Sender: TObject; Item1,
  Item2: TListItem; Data: Integer; var Compare: Integer);
begin
 with TListView(Sender) do
  if Tag = 0 then
   Compare := InverseValue(CompareText(Item1.Caption, Item2.Caption), Columns[Tag].Tag = 0)
  else
   Compare := InverseValue(CompareText(Item1.SubItems[Tag-1], Item2.SubItems[Tag-1]), Columns[Tag].Tag = 0)
end;

Open in new window

Avatar of urif
urif

ASKER

@SteveBay:

thanks, but all this code does is to throw an exception when i add a new item to the list


@sas13:

thanks, but as i mentioned the user DOES NOT click on the column. There is no column clicking.

i'll try to explain myself better.

One list view with 2 colums (NON CLICKABLE)
list is sorted using the SortType:=stText
in the options windows (where the user sets the options for the program) there is a checkbox that state the following: sort by priority. Priority is the second column (subitem(0))
when the user checks that option that list needs to be sorted by the text in subitem(0).

i hope i explained myself better this time.
again, there is no clicking on columns

thanks
ASKER CERTIFIED SOLUTION
Avatar of Russell Libby
Russell Libby
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial