Sorting TListView

Hello, I would sort a TListView by Clicking on the column (containes DateTime). Could You help me there?
LVL 4
k4hvd77Asked:
Who is Participating?
 
sftwengConnect With a Mentor Commented:
OK, here's a framework for sorting, built on the TListView example in the help files:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ImgList, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    ImageList1: TImageList;
    ComboBox1: TComboBox;
    StatusBar1: TStatusBar;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Click(Sender: TObject);
    procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn);
    procedure ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  initialized : BOOLEAN;

implementation

{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  ListItem: TListItem;
  NewColumn: TListColumn;
begin
  // Create a ListView item for each image in the ImageList
  initialized := FALSE;
  with ListView1 do
  begin
    SmallImages := ImageList1;
    LargeImages := ImageList1;
    for I := 0 to ImageList1.Count - 1 do
    begin
      ListItem := Items.Add;
      Listitem.Caption := 'Image' + IntToStr(I);
      ListItem.SubItems.Add(DateTimeToStr(Now));
      ListItem.ImageIndex := I;
    end;
    // Create two columns to show during viewing as vsReport
//    NewColumn := Columns.Add;
//    NewColumn.Caption := 'Column 1';
//    NewColumn := Columns.Add;
//    NewColumn.Caption := 'Column 2';
    // Add View styles and constants to the Combo Box
    ComboBox1.Items.AddObject('vsIcon', TObject(vsIcon));
    ComboBox1.Items.AddObject('vsList', TObject(vsList));
    ComboBox1.Items.AddObject('vsReport', TObject(vsReport));
    ComboBox1.Items.AddObject('vsSmallIcon', TObject(vsSmallIcon));
    // Display first item in the Combo Box
    ComboBox1.ItemIndex := 0;
  end;
  initialized := TRUE;
end;

procedure TForm1.ComboBox1Click(Sender: TObject);
begin
  with ComboBox1 do
    ListView1.ViewStyle := TViewStyle(Items.Objects[ItemIndex]);
end;

procedure TForm1.ListView1ColumnClick(Sender: TObject;
  Column: TListColumn);
VAR
  colID : INTEGER;
  colIndex : INTEGER;
begin
  colID := Column.ID;
  colIndex := Column.Index;
  StatusBar1.Panels[0].Text := 'ID:'+IntToStr(ColID);
  StatusBar1.Panels[1].Text := 'IX:'+IntToStr(ColIndex);
  ListView1.AlphaSort;
end;

procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
VAR
  ax, bx : INTEGER;
  aVal, bVal : String;
begin
  IF initialized
  THEN BEGIN
    ax := Item1.Index; bx := Item2.Index;
    aVal := Item1.SubItems[0];
    bVal := Item2.SubItems[0];
    StatusBar1.Panels[2].Text := 'AV:'+aVal;
    StatusBar1.Panels[3].Text := 'BV:'+bVal;
  END {IF};
end;

end.

In the ListView1Compare event handler, you'll need to convert the string representation of the TDateTimes back into a TDateTime for the two ListItems to be compared (compare them as TDateTimes rather than strings), and return a value indicating whether a < b, a = b, or a > b.

Let me know if this doesn't get you going.
0
 
sftwengCommented:
The first part is to determine which column the mouse is in. Try something like this:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    StatusBar1: TStatusBar;
    procedure ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  StatusBar1.Panels[0].Text := IntToStr(x);
  StatusBar1.Panels[1].Text := IntToStr(y);
  IF (X > ListView1.Columns[0].Width)
  THEN StatusBar1.Panels[2].Text := 'Column 2'
  ELSE StatusBar1.Panels[2].Text := 'Column 1';
end;

end.
0
 
sftwengCommented:
Of course a better way to get the column is to use an OnColumnClick event.

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

end;
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

 
k4hvd77Author Commented:
but How can I sort it?
0
 
sftwengCommented:
Do you want to sort by Caption, Data or Both?
0
 
k4hvd77Author Commented:
I would sort by caption (Caption contains TDateTime)
0
 
k4hvd77Author Commented:
Exact that what I want :)
0
All Courses

From novice to tech pro — start learning today.