Содержание материала

 

Сортировка ListView в режиме vsReport при нажатии на заголовок колонки

 

Code:

function CustomDateSortProc(Item1, Item2: TListItem; ParamSort: integer): integer; stdcall;

 

begin

result:=0;

if strtodatetime(item1.SubItems[0])> strtodatetime(item2.SubItems[0]) then

Result :=1

else

if strtodatetime(item1.SubItems[0])< strtodatetime(item2.SubItems[0]) then

   Result :=-1;

end;

 

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

begin

if column =lv1.columns[0] then

LV1.CustomSort(@CustomNameSortProc, 0)

else

LV1.CustomSort(@CustomDateSortProc, 0)

end;

 

Сортировка по первой колонке

Сортировка по первой колонке TListView делается так:

 

Code:

ListView1.SortType := stText;

  

Установка SortType в stText аналогична установке Sorted в True в объекте TListBox. Список будет оставаться отсортированным даже после добавления или изменения элементов, до тех пор, пока не установить SortType обратно в stNone:

Code:

ListView1.SortType := stNone;

  

В TListBox это аналогично установке Sorted в False.

 

Сортировка по другим колонкам

Чтобы отсортировать TListView по другой колонке, потребуется написать событие OnCompare, либо функцию сортировки, которая будет использоваться в методе CustomSort.

 

Для начала рассмотрим сортировку при помощи события OnCompare.

Code:

procedure(Sender: TObject; Item1, Item2: TListItem;Data: Integer; var Compare: Integer) of object;

 

 Параметр Compare может иметь три значения: 1, -1 или 0. Единица означает, что первый элемент больше (или должен быть размещён после) второго элемента. Минус одни означает, что первый элемент меньше чем (или должен быть размещён перед) второй элемент. Ноль означает, что два элемента равны.

 

В следующем примере мы сортируем TListView по четвёртой колонке (которая представлена целыми значениями) в порядке убывания:

Code:

procedure TForm1.ListView1Compare(Sender: TObject; Item1,

Item2: TListItem; Data: Integer; var Compare: Integer);

var

n1, n2: integer;

begin

n1 := StrToInt(Item1.SubItems[2]);

n2 := StrToInt(Item2.SubItems[2]);

if n1 > n2 then

   Compare := -1

else if n1 < n2 then

   Compare := 1

else

   Compare := 0;

end;


 

Теперь достаточно установить SortType в stBoth (вместо stText, который сортирует по первой колонке не используя метод OnCompare):

 

ListView1.SortType := stBoth;

 

Теперь, чтобы сделать временную сортировку, проделайте следующее:

 

ListView1.SortType := stBoth;

ListView1.SortType := stNone;

 

или ещё:

 

ListView1.CustomSort(nil, 0);

 

Сортировка при помощи функции сортировки

Функция сортировки используется для быстрой сортировки. Эта функция должна возвращать 1, -1 или 0 (как параметр Compare в событии OnCompare). Например:

Code:

function ByFourth(Item1, Item2: TListItem; Data: integer):

integer; stdcall;

var

n1, n2: cardinal;

begin

n1 := StrToInt(Item1.SubItems[2]);

n2 := StrToInt(Item2.SubItems[2]);

if n1 > n2 then

   Result := -1

else if n1 < n2 then

   Result := 1

else

   Result := 0;

end;

  

Теперь, каждый раз, как Вы захотите отсортировать список, достаточно будет вызвать метод CustomSort, передав ему адрес функции сортировки. Например:

 

ListView1.CustomSort(@ByFourth, 0);

 

Параметр Data в функции сортировки используется для указания номера колонки.


Code:

unit SortedListView;

 

interface

 

uses

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

  ComCtrls;

 

type

  TSortedListView = class(TListView)

  private

    FSortColumn: Integer;

    procedure SetSortColumn(const Value: Integer);

    procedure SortedListViewCompare(Sender: TObject; Item1, Item2: TListItem;

      Data: Integer; var Compare: Integer);

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

    { Private declarations }

  protected

    { Protected declarations }

  public

    constructor Create(AOwner: TComponent); override;

    { Public declarations }

  published

    { Published declarations }

    property SortColumn: Integer read FSortColumn write SetSortColumn;

  end;

 

implementation

 

{==============================================================================}

{ TSortedListView }

{==============================================================================}

constructor TSortedListView.Create(AOwner: TComponent);

begin

  inherited;

 

  OnColumnClick := SortedListViewColumnClick;

  OnCompare := SortedListViewCompare;

end;

{==============================================================================}

 

procedure TSortedListView.SetSortColumn(const Value: Integer);

begin

  FSortColumn := Value;

  AlphaSort;

end;

{==============================================================================}

 

procedure TSortedListView.SortedListViewColumnClick(Sender: TObject;

  Column: TListColumn);

begin

  SortColumn := Column.Index;

end;

{==============================================================================}

 

procedure TSortedListView.SortedListViewCompare(Sender: TObject;

  Item1, Item2: TListItem; Data: Integer; var Compare: Integer);

begin

  if SortColumn = 0 then

    Compare := CompareText(Item1.Caption, Item2.Caption)

  else

    Compare := CompareText(Item1.SubItems[SortColumn - 1], Item2.SubItems[SortColumn - 1]);

end;

 

end.

 


Code:

{

This example shows how to use the TListView's CustomSort method to

sort the items in the list using a ordering function.

This allows you to sort custom data in the correct order you want.

 

When the user clicks on a column header, the ListView will be sorted

by that column.

If the user clicks on the same column again, the sort order will be toggled.

}

 

{ custom sort styles }

 

type

  TCustomSortStyle = (cssAlphaNum, cssNumeric, cssDateTime);

 

var

  { variable to hold the sort style }

  LvSortStyle: TCustomSortStyle;

  { array to hold the sort order }

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

 

implementation

 

{$R *.DFM}

 

function CustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): Integer; stdcall;

var

  s1, s2: string;

  i1, i2: Integer;

  r1, r2: Boolean;

  d1, d2: TDateTime;

 

  { Helper functions }

 

  function IsValidNumber(AString : string; var AInteger : Integer): Boolean;

  var

    Code: Integer;

  begin

    Val(AString, AInteger, Code);

    Result := (Code = 0);

  end;

 

  function IsValidDate(AString : string; var ADateTime : TDateTime): Boolean;

  begin

    Result := True;

    try

      ADateTime := StrToDateTime(AString);

    except

      ADateTime := 0;

      Result := False;

    end;

  end;

 

  function CompareDates(dt1, dt2: TDateTime): Integer;

  begin

    if (dt1 > dt2) then Result := 1

    else

      if (dt1 = dt2) then Result := 0

    else

      Result := -1;

  end;

 

  function CompareNumeric(AInt1, AInt2: Integer): Integer;

  begin

    if AInt1 > AInt2 then Result := 1

    else

      if AInt1 = AInt2 then Result := 0

    else

      Result := -1;

  end;

 

begin

  Result := 0;

 

  if (Item1 = nil) or (Item2 = nil) then Exit;

 

  case SortColumn of

    -1 :

    { Compare Captions }

    begin

      s1 := Item1.Caption;

      s2 := Item2.Caption;

    end;

    else

    { Compare Subitems }

    begin

      s1 := '';

      s2 := '';

      { Check Range }

      if (SortColumn < Item1.SubItems.Count) then

        s1 := Item1.SubItems[SortColumn];

      if (SortColumn < Item2.SubItems.Count) then

        s2 := Item2.SubItems[SortColumn]

    end;

  end;

 

  { Sort styles }

 

  case LvSortStyle of

    cssAlphaNum : Result := lstrcmp(PChar(s1), PChar(s2));

    cssNumeric  : begin

                    r1 := IsValidNumber(s1, i1);

                    r2 := IsValidNumber(s2, i2);

                    Result := ord(r1 or r2);

                    if Result <> 0 then

                      Result := CompareNumeric(i2, i1);

                  end;

    cssDateTime : begin

                    r1 := IsValidDate(s1, d1);

                    r2 := IsValidDate(s2, d2);

                    Result := ord(r1 or r2);

                    if Result <> 0 then

                      Result := CompareDates(d1, d2);

                  end;

  end;

 

  { Sort direction }

 

  if LvSortOrder[SortColumn + 1] then

    Result := - Result;

end;

 

 

{ The ListView's OnColumnClick event }

 

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

begin

  { determine the sort style }

  if Column.Index = 0 then

    LvSortStyle := cssAlphaNum

  else

    LvSortStyle := cssNumeric;

 

  { Call the CustomSort method }

  ListView1.CustomSort(@CustomSortProc, Column.Index -1);

 

  { Set the sort order for the column}

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

end;

 

 

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить