Practical developers (dexSoft.ru)
Домены
 
Опубликовать
Обсуждения
Марс атакует!
Сгинули все инопланетяне... Надоели мы им...
Статьи > Delphi

Сортировка элементов в TListView и TTreeView

28 апрель 2009 16:25, рейтинг: 102446, автор: EloSoft

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 в отдельности.

Новый комментарий
Пользователь:
Protected codeОбновить
RSS  RSS
Сайт dexsoft.ru использует cookie-файлы и подобные технологии для улучшения обслуживания посетителей.Закрыть