Solved

Sorting a Listview by colums

Posted on 1998-07-17
10
271 Views
Last Modified: 2008-02-01
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
Comment
Question by:jpcs
10 Comments
 
LVL 5

Expert Comment

by:mayhew
ID: 1358131
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
 

Accepted Solution

by:
bome earned 20 total points
ID: 1358132
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
 
LVL 1

Author Comment

by:jpcs
ID: 1358133
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
 
LVL 1

Author Comment

by:jpcs
ID: 1358134
Sorry everybody, but in fact it is a ListView control, not a ListBox. Sorry.
0
 

Expert Comment

by:bome
ID: 1358135
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:jpcs
ID: 1358136
Thanks.
0
 
LVL 1

Author Comment

by:jpcs
ID: 1358137
Just another thing : Can you tell me how to avoid the user to resize any column header?

Thanks
0
 

Expert Comment

by:bome
ID: 1358138
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
 

Expert Comment

by:bome
ID: 1358139
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
 

Expert Comment

by:ibrobar
ID: 10632280
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video discusses moving either the default database or any database to a new volume.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now