Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 326
  • Last Modified:

Sorting a Listview by colums

how can I sort a listbox by clicking a column? I've tried changing the columsclick event, but unsucessfuly. How can I do it. Thanks.
0
jpcs
Asked:
jpcs
1 Solution
 
mayhewCommented:
Is it that you want to sort the whole listbox by clicking on any column?

If so, in the ListBox1OnClick method:
  ListBox1.Sorted := true;

If I am misunderstanding your question, please rephrase it and we'll take another look.  :)
0
 
bomeCommented:
I assume that your listbox is a TListView. Let's call it ListView:
Create handlers for OnColumnClick and OnCompare:

procedure TForm1.ListViewColumnClick(Sender: TObject;
  Column: TListColumn);
begin
 ListView.CustomSort(nil,Column.index);
end;


procedure TForm1.ListViewCompare(Sender: TObject; Item1,
  Item2: TListItem; Data: Integer; var Compare: Integer);
begin
 if (Item1=nil) and (Item2=nil) then
  Compare:=0
 else
 if (Item1=nil) and (Item2<>nil) then
  Compare:=-1
 else
 if (Item1<>nil) and (Item2=nil) then
  Compare:=1
 else
 if Data=0 then
  Compare:=ComPareStr(Item1.Caption,Item2.Caption)
 else
 // sanity check
 if (Data<=Item1.SubItems.Count) and (Data<=Item2.SubItems.Count) then
  Compare:=ComPareStr(Item1.SubItems[Data-1],Item2.SubItems[Data-1]);
 // sort by name as second criteria
 if (Compare=0) and (Data<>0) then
  ListViewCompare(sender,Item1,Item2,0,Compare);
end;

These procedures sort alphanumerically the respective column when you click on the column header.

bome
0
 
jpcsAuthor Commented:
Thanks for the grat answer bome. Gee, It's was far more dificult than I thought.

There are some tinny little problems that I would thank you if you help me :

1. If I click a column, it does now sort the items (from a to z), but if I click it again, it should resort from z to a. How can I do it?

2. Why is "T" (upcase) before "a" (lowercase) and why is "2" after "10"? How can I solve this? (I don't want to use "02" instead "2".


Thank you very much for your answer.

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jpcsAuthor Commented:
Sorry everybody, but in fact it is a ListView control, not a ListBox. Sorry.
0
 
bomeCommented:
Hi,
no problem.
1. add 2 variables to your form: e.g.
sortIndex: Integer;
reversesort:boolean;

in the ColumnsClick handler you add at the beginning:
if sortIndex=Column.index then
 reverseSort:=not reverseSort;
sortIndex:=Column.Index;

Replace the last 2 lines in the ListViewCompare procedure with these:
if (Compare=0) and (Data<>0) then
      ListViewCompare(sender,Item1,Item2,0,Compare)
else
if reverseSort then
 Compare:=-Compare;

2. To have case insensitive sort, replace all CompareStr with CompareText.

That's it, thank you for the points !
bome
0
 
jpcsAuthor Commented:
Thanks.
0
 
jpcsAuthor Commented:
Just another thing : Can you tell me how to avoid the user to resize any column header?

Thanks
0
 
bomeCommented:
no, I don't. I think this is intended by Microsoft - try Ctrl+'+' - it resizes automatically. So you would have to care about some events. The only thing I can imagine is to access the listview directly with windows API - I don't have the time at the moment to check this out. The names of these "functions" start all with "ListView_"...

Another thing why this could get a problem: Column width is in pixels - but what if the user changes the standard font size ? I haven't tried, but very probably the column titles change size, too, so eventually the user wouldn't be able to read the column title when he has big fonts.

bome
0
 
bomeCommented:
no, I don't. I think this is intended by Microsoft - try Ctrl+'+' - it resizes automatically. So you would have to care about some events. The only thing I can imagine is to access the listview directly with windows API - I don't have the time at the moment to check this out. The names of these "functions" start all with "ListView_"...

Another thing why this could get a problem: Column width is in pixels - but what if the user changes the standard font size ? I haven't tried, but very probably the column titles change size, too, so eventually the user wouldn't be able to read the column title when he has big fonts.

bome
0
 
ibrobarCommented:
Dear Bome

I want to thank u for the great solution and for your help
I am having a problem with a listview too let me explain it
I have a listview with 6 static columns.
I have a popup menu attached with the listview.From the popup menu i can call listbox showing table fields.
what I need to do is to drag and drop from that listbox to the listview and to get the effects due to the drag and drop event.
here is my code: {I applied this code on listviewDragdrop procedure}

var I:integer;
    NewColumn: TListColumn;
    ListItem:TListItem;
    S:String;
begin
if (sender=listview1) and (source=form10.ListBox1) then
For i := 0 to (Form10.ListBox1.Items.Count - 1) do begin
   if Form10.ListBox1.Selected[i] then begin
      NewColumn:= listview1.Columns.add;
      NewColumn.Caption :=Form10.listbox1.items.Strings[i];
      NewColumn.Width:=100;
      S:=Form10.listbox1.items.Strings[i];
   end;
end;
DataModule1.Query13.Open;
If DataModule1.Query13.RecordCount<>0 then begin
     ListView1.Items.Clear;
     DataModule1.Query13.First;
    while not DataModule1.QUERY13.EOF do begin
       listitem:=Form2.listview1.Items.Add;
       listitem.Caption:=DataModule1.Query13['TITLE'];
       listitem.SubItems.Add(DataModule1.Query13['atitle']);
       listitem.SubItems.Add(DataModule1.Query13['borrower']);
       listitem.SubItems.Add(DataModule1.Query13['overdue']);
       listitem.SubItems.Add(DataModule1.Query13['cdate']);
       listitem.SubItems.Add(DataModule1.Query13['bdepartment']);
       Listitem.SubItems.Add(DataModule1.Query13[s]);
       listitem.ImageIndex:=0;
       DataModule1.QUERY13.Next;
   end;
end

as you can see from my code that I am adding new columns with out having any problems and i can add one subitems prefectly but when I want to drag and drop another item from the listbox the new subitems is coming over the old one cause you know it's coming at the end of the listview items.
I tried the insert procedure it didn't work , I tried many loops but I am still having the same problem
so can I get your help here.
one more thing how can  save the new layout of the listview so i can ask get again when I want the same layout.

thanks a lot

regards
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now