Solved

Sorting a Virtual Listview

Posted on 2007-11-20
6
1,963 Views
Last Modified: 2012-08-13
Hi,
I asked a question sometime ago (http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_21718319.html?sfQueryTermInfo=1+listview+virtual) and would liek some addtional help.

In the solution given in the link above - I am left with MyList. This virtual list is displayed in a listview. Can somebody show me how to sort this now when I click on one of the three column headers.

I would appreciate some working code if possible.
0
Comment
Question by:Romans
  • 3
  • 3
6 Comments
 
LVL 14

Expert Comment

by:SteveBay
ID: 20323762
You need to sort your list and then redisplay the contents.
This code fragment is not complete but has the principal parts.
Let me know if you need more detail.

Steve
function SortWord(Item1,Item2 : pointer) : integer;

begin

 result := CompareText( TOccurrence(Item1).TheWord, TOccurrence(Item2).TheWord);

end;
 

function SortCount(Item1,Item2 : pointer) : integer;

begin

 result := TOccurrence(Item2).Count - TOccurrence(Item1).Count;

end;
 

function SortFirstPos(Item1,Item2 : pointer) : integer;

begin

 result := TOccurrence(Item2).FirstPos - TOccurrence(Item1).FirstPos;

end;
 

procedure TForm1.ListView1ColumnClick(Sender: TObject;    Column: TListColumn);

begin

	if Column.Index = 0 then

		MyList.Sort(SortWord)

	else if Column.Index = 1 then

		MyList.Sort(SortCount)

	else if Column.Index = 2 then

		MyList.Sort( SortFirstPos);
 

	// Refresh ListView Display.

end;

Open in new window

0
 
LVL 14

Accepted Solution

by:
SteveBay earned 500 total points
ID: 20323897
Here is the complete working Unit. I made a minor mistake in the number sort routines.
It sould be Item1 - Item2 not Item2 - Item1

Steve
unit Unit1;
 

interface
 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ComCtrls, Contnrs;

type

  TOccurrence = class

    TheWord: string;

    Count: integer;

    FirstPos: integer;

  end;
 

type

  TForm1 = class(TForm)

    ListView1: TListView;

    procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn);

    procedure FormShow(Sender: TObject);

    procedure ListView1Data(Sender: TObject; Item: TListItem);

    procedure FormClose(Sender: TObject; var Action: TCloseAction);

  private

	MyList : TObjectList;
 

    { Private declarations }

  public

    { Public declarations }

  end;
 

var

  Form1: TForm1;
 

implementation
 

{$R *.dfm}

function SortWord(Item1,Item2 : pointer) : integer;

begin

	result := CompareText( TOccurrence(Item1).TheWord, TOccurrence(Item2).TheWord);

end;
 

function SortCount(Item1,Item2 : pointer) : integer;

begin

	result := TOccurrence(Item1).Count - TOccurrence(Item2).Count;

end;
 

function SortFirstPos(Item1,Item2 : pointer) : integer;

begin

	result := TOccurrence(Item1).FirstPos - TOccurrence(Item2).FirstPos;

end;
 
 
 

procedure TForm1.ListView1ColumnClick(Sender: TObject;    Column: TListColumn);

begin

	if Column.Index = 0 then

		MyList.Sort(SortWord)

	else if Column.Index = 1 then

		MyList.Sort(SortCount)

	else if Column.Index = 2 then

		MyList.Sort( SortFirstPos);
 

	ListView1.Refresh;

end;
 

procedure TForm1.FormShow(Sender: TObject);

var oc  : TOccurrence;

begin

	MyList := TObjectList.Create;
 

	oc := TOccurrence.Create;

	oc.TheWord := 'The';

	oc.Count := 2;

	oc.FirstPos := 0;

	MyList.Add(oc);
 

	oc := TOccurrence.Create;

	oc.TheWord := 'brown';

	oc.Count := 2;

	oc.FirstPos := 4;

	MyList.Add(oc);
 

	oc := TOccurrence.Create;

	oc.TheWord := 'dog';

	oc.Count := 1;

	oc.FirstPos := 10;

	MyList.Add(oc);
 
 

	oc := TOccurrence.Create;

	oc.TheWord := 'jumped';

	oc.Count := 1;

	oc.FirstPos := 14;

	MyList.Add(oc);
 

	oc := TOccurrence.Create;

	oc.TheWord := 'over';

	oc.Count := 1;

	oc.FirstPos := 21;

	MyList.Add(oc);
 

	oc := TOccurrence.Create;

	oc.TheWord := 'fence';

	oc.Count := 1;

	oc.FirstPos := 36;

	MyList.Add(oc);

	ListView1.Items.Count := MyList.Count;

end;
 

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);

begin

	Item.Caption := TOccurrence(MyList[Item.Index]).TheWord;

	Item.SubItems.Add(IntToStr(TOccurrence(MyList[Item.Index]).Count));

	Item.SubItems.Add(IntToStr(TOccurrence(MyList[Item.Index]).FirstPos));

end;
 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

	MyList.Free

end;
 

end.

Open in new window

0
 

Author Comment

by:Romans
ID: 20326963
Thanks for the help - really appreciated. I added the ability to sort ascending and decending. Here is what I ended up with...

If you know how to get the little up/down arrows to appear on the top of the column headers when sorted let me know.

Thanks
Romans
unit Unit1;
 

interface
 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ComCtrls, Contnrs;
 

type

  TOccurrence = class

    TheWord: string;

    Count: integer;

    FirstPos: integer;

  end;
 
 

type

  TForm1 = class(TForm)

    ListView1: TListView;

    procedure ListView1Data(Sender: TObject; Item: TListItem);

    procedure FormShow(Sender: TObject);

    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn);

  private

    MyList : TObjectList;
 

    { Private declarations }

  public

    { Public declarations }

  end;
 

var

  Form1: TForm1;

  LvSortOrder: array[0..4] of Boolean; // High[LvSortOrder] = Number of Lv Columns

  SortColumn : Integer;
 

implementation
 

{$R *.dfm}
 

function SortWord(Item1,Item2 : pointer) : integer;

begin

	result := CompareText( TOccurrence(Item1).TheWord, TOccurrence(Item2).TheWord);
 

    if LvSortOrder[SortColumn] then

        Result := - Result;

end;

 

function SortCount(Item1,Item2 : pointer) : integer;

begin

	result := TOccurrence(Item1).Count - TOccurrence(Item2).Count;
 

    if LvSortOrder[SortColumn] then

        Result := - Result;
 

end;
 

function SortFirstPos(Item1,Item2 : pointer) : integer;

begin

	result := TOccurrence(Item1).FirstPos - TOccurrence(Item2).FirstPos;
 

    if LvSortOrder[SortColumn] then

        Result := - Result;

end;
 
 

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);

begin

	Item.Caption := TOccurrence(MyList[Item.Index]).TheWord;

	Item.SubItems.Add(IntToStr(TOccurrence(MyList[Item.Index]).Count));

	Item.SubItems.Add(IntToStr(TOccurrence(MyList[Item.Index]).FirstPos));

end;
 

procedure TForm1.FormShow(Sender: TObject);

var oc  : TOccurrence;

begin

	MyList := TObjectList.Create;

 

	oc := TOccurrence.Create;

	oc.TheWord := 'The';

	oc.Count := 2;

	oc.FirstPos := 0;

	MyList.Add(oc);

 

	oc := TOccurrence.Create;

	oc.TheWord := 'brown';

	oc.Count := 2;

	oc.FirstPos := 4;

	MyList.Add(oc);

 

	oc := TOccurrence.Create;

	oc.TheWord := 'dog';

	oc.Count := 1;

	oc.FirstPos := 10;

	MyList.Add(oc);

 

 

	oc := TOccurrence.Create;

	oc.TheWord := 'jumped';

	oc.Count := 1;

	oc.FirstPos := 14;

	MyList.Add(oc);

 

	oc := TOccurrence.Create;

	oc.TheWord := 'over';

	oc.Count := 1;

	oc.FirstPos := 21;

	MyList.Add(oc);

 

	oc := TOccurrence.Create;

	oc.TheWord := 'fence';

	oc.Count := 1;

	oc.FirstPos := 36;

	MyList.Add(oc);

	ListView1.Items.Count := MyList.Count;

end;
 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

MyList.Free;

end;
 

procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);

begin

    SortColumn := Column.Index;
 

	if Column.Index = 0 then

		MyList.Sort(SortWord)

	else if Column.Index = 1 then

		MyList.Sort(SortCount)

	else if Column.Index = 2 then

		MyList.Sort(SortFirstPos);
 

	ListView1.Refresh;
 

    LvSortOrder[Column.Index] := not LvSortOrder[Column.Index];
 

end;
 

end.

Open in new window

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Closing Comment

by:Romans
ID: 31410212
Thanks!!
0
 
LVL 14

Expert Comment

by:SteveBay
ID: 20328494
Put an imagelist on your form. Add two small images, an up arrow and a down arrow. Then put this code in your ListView1ColumnClick event

for i := 0 to ListView1.Columns.Count - 1 do
  ListView1.Columns[i].ImageIndex := -1;
if LvSortOrder[Column.Index] then
 Column.ImageIndex := 0
else
 Column.ImageIndex := 1;

0
 

Author Comment

by:Romans
ID: 20328510
Thanks Steve - Great help to me and I really appreciate it!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Filemaker 14 vs Delphi Embarcadero 7 185
Delphi with SQL Natvie Client 15 85
ddeman not working in activex 3 92
Can Viruses spread while transferring Binary data with Winsock 2 66
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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

919 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

12 Experts available now in Live!

Get 1:1 Help Now