TListView
Сортировка TListView и TTreeView может быть выполнена установкой свойства SortType в инспекторе объектов. Если надо получить всегда одну и ту же сортировку элементов, достаточно задать свойство SortType, но необходимо учитывать следующее: без обработчика события OnCompare сортировка будет выполняться только для значения SortType=stText, для других значений свойства SortType необходимо задать обработчик события OnCompare и сортировка будет выполняться только в RunTime.
Более широкие возможности сортировки предоставляет функция AlphaSort. Эта функция возвращает True при успешном выполнении. Если обработчик события OnCompare не определен и свойство SortType не равно stNone функция AlphaSort сортирует все элементы списка в алфавитном порядке по возрастанию. Если задан обработчик события OnCompare позиция элемента списка будет определяться именно этим обработчиком.
Рассмотрим использование функции AlphaSort при заданном обработчике события OnCompare.
Определим пару переменных, которые будут использоваться для сортировки.
implementation var lvSortItemIndex: Integer = -1; lvReverse: integer = 1;
В переменной lvSortItemIndex будет храниться значение индекса колонки, по элементам которой выполнена сортировка.
Переменная lvReverse определяет направление сортировки: по возрастанию или убыванию.
Используем событие OnColumnClick для задания и изменения сортировки (свойство ColumnClick должно быть установлено в True). Логика этой процедуры очень проста: если индекс выбранной колонки не равен индексу колонки, по которой выполнена текущая сортировка, то сохраняем индекс колонки в переменной lvSortItemIndex и устанавливаем направление сортировки по возрастанию (lvReverse:= 1), иначе меняем направление сортировки.
procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin if lvSortItemIndex<> Column.Index then begin lvSortItemIndex:= Column.Index; lvReverse:= 1; end else lvReverse:= lvReverse* (-1); (Sender as TListView).AlphaSort; end;
Обработчик события OnCompare может выглядеть следующим образом.
procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); var ix: Integer; begin if lvSortItemIndex = 0 then Compare:= CompareText(Item1.Caption,Item2.Caption) else begin ix:= lvSortItemIndex- 1; Compare:= CompareText(Item1.SubItems[ix],Item2.SubItems[ix]); end; Compare:= Compare* lvReverse; end;
Условие if lvSortItemIndex = 0 необходимо для того, чтобы определить с каким списком выполняется действие. Если lvSortItemIndex=0 – это основной список, иначе это список субэлементов. Выражение ix:= lvSortItemIndex- 1 определяет индекс субэлемента. Сравнивать текстовые значения можно с помощью функций CompareText, CompareStr, AnsiCompareText, AnsiCompareStr или использовать собственные функции сравнения. Для числовых значений можно использовать например такое выражение:
if StrToInt(Item1.Caption)< StrToInt(Item2.Caption) then Compare:= -1 else if StrToInt(Item1.Caption)> StrToInt(Item2.Caption) then Compare:= 1 else Compare:= 0;
Параметр Data при использовании функции AlphaSort всегда равен 0 и используется функцией CustomSort, которая в этой статье не рассматривается.
Параметр Compare определяет, как изменится положение элемента в списке. Для данного примера значение Compare будет определять следующее: если Compare=0 положение Item1 и Item2 относительно друг друга не измениться, если Compare=1 сначала будет выведен Item1 и за ним Item2, если Compare=-1 сначала будет выведен Item2 и за ним Item1.
TTreeView.
Сортировка в TTreeView практически идентична сортировке в TListView. Разница состоит лишь в том, что в функции AlphaSort можно передать логический параметр ARecurse, который определяет сортировать или нет вложенные элементы древа, а также сортировку можно выполнять не только для всего древа, но и для каждого объекта типа TTreeNode в отдельности.
Сгинули все инопланетяне... Надоели мы им...
Круто!!!