Перейти к содержанию
Fire Monkey от А до Я
  • 0

Сортировка с использованием функции TTreeView.Sort


i.r.khayrullin

Вопрос

Опубликовано

Добрый день!

 

Пытаюсь отсортировать элементы дерева таким образом:

procedure TForm1.SortTreeItemsClick(Sender: TObject);
begin
  TreeView1.Sort(MySortTree);
  TreeView1.RealignContent;
end;

Элементы дерева приводятся на свое место, но их отображение прекращается. Некоторые элементы видны как фантомы, некоторые - пустые строки. 

 

Перепробовал всё, пытаясь обновить дерево, ничего не удалось. Демка во вложении, там есть работающий вариант с ListBox.

TestingSort.zip

Рекомендуемые сообщения

  • 0
Опубликовано (изменено)

По приложенному примеру:

  1. в MySortTree нужно TTreeViewItem вместо TListBoxItem.
  2. при работе с TListBox и TTreeVew (заполнение и пр.) рекомендую использовать .BeginUpdate и .EndUpdate.

По проблеме:
Так вроде показывает без фантомов:

procedure TForm1.SortTreeItemsClick(Sender: TObject);
begin
  TreeView1.BeginUpdate;
  try
    TreeView1.Sort(MySortTree);
    TreeView1.ExpandAll;
  finally
    TreeView1.EndUpdate;
  end;
end;

P.S. А Вы используете какое-то особое правило сортировки? Если нет, рекомендую просто использовать TreeView1.Sorted := true для автоматической сортировки в алфавитном порядке по тексту в айтемах.

Изменено пользователем Brovin Yaroslav
  • 0
Опубликовано

  1. Да, ошибка вышла, торопился написать пример. В рабочем проекте, конечно никаких ListBoxItem небыло.
  2. Спасибо, обычно использую. Просто старался минимизировать пример, что бы найти проблему методом "проб". Пробовал и том числе и BeginUpdate - не помогало.

А вот про ExpandAll я бы не догадался. Почему так? Не понимаю.

procedure TCustomTreeView.ExpandAll;
var
  i: Integer;
  Item: TTreeViewItem;
begin
  BeginUpdate;
  try
    for i := Count - 1 downto 0 do
    begin
      Item := Items[i];
      if Item <> nil then
        Item.ExpandAll;
    end;
  finally
    EndUpdate;
  end;
end;

Не пойму, что в этом коде заставляет TreeView "обновиться"? Отдельно конструкция BegniUpdate > EndUpdate не работает.

 

По поводу Sorted:= True, да, в моем проекте элементы будут сортироваться по определенным правилам. На верхнем уровне сортировки вообще не будет. 

 

Спасибо.

  • 0
  • Администраторы
Опубликовано

Выравнивать итемы заставляет метод EndUpdate. Но только, если были внутри секции BeginUpdate/EndUpdate были изменения требующие выравнивания.

 

Если хотите форсировать выравнивание, это можно сделать так:

(TreeView1 as IAlignRoot).Realign;
  • 0
  • Администраторы
Опубликовано

Чтобы отсортировать TTreeView нужно делать так:

  1. Устанавливаете свойство TTreeView.Sorted = True
  2. Задаем обработчик сравнения TTreeView.OnCompare.
  • 0
Опубликовано (изменено)
В 12.02.2016 в 20:11, Brovin Yaroslav сказал:

Чтобы отсортировать TTreeView нужно делать так:

  1. Устанавливаете свойство TTreeView.Sorted = True
  2. Задаем обработчик сравнения TTreeView.OnCompare.

есть такая процедура

Цитата

 procedure TForm1.bnRundomClick(Sender: TObject);
var
  C:integer;
  i: Integer;
  TreeViewItem: TTreeViewItem;
begin
  TreeView1.Sorted:=false;
  TreeView1.BeginUpdate;
  C:=Random(StrToIntDef(Edit1.Text,15))+1;//случайное количество
  for i := 0 to C do
  begin//добавляется случайное число узлов
    TreeViewItem:=TTreeViewItem.Create(TreeView1);
    TreeViewItem.Text:=Format('%.*d',[3,Random(1000)]);//случайное имя узла от 0 до 1000
    TreeViewItem.Parent:=TreeView1;
  end;
  //!!!!!!!!!!!!!!!
  TreeView1.ExpandAll;
  TreeView1.EndUpdate;
  TreeView1.Sorted:=true;
end;

В результате получается список узлов в корне с случайными именами. Процедура TreeView1Compare вызывается в момент TreeView1.Sorted:=true; и сортирует узлы в правильном порядке. Все прекрасно.

Если вместо //!!!!!!!!!!!!!!! добавить вот такой блок

Цитата

  for i := TreeView1.Count-1 downto 1 do
  begin
    C:=Random(i-1);
    TreeView1.Items[i].Parent:=TreeView1.Items[C];
  end;

перемещающий узлы дерева из корня и превращающий список в дерево, то TreeView1Compare не вызывается! Как это можно исправить? нужно сортировать дерево.

 

UPD. Этот блок перемещает все узлы в самый первый. Если оставить несколько узлов в корне, то процедура сортировки вызывается, но сортирует только верхний уровень. вложенные уровни не сортируются. Как быть с сортировкой внутри веток?

 

Изменено пользователем Frol
  • 0
Опубликовано

Эксперименты показали, что TreeView.Sorted:=true сортирует только верхний уровень. Каждый вложенный  узел надо сортировать через TreeViewItem.Sort(). При этом могут возникать дефекты визуализации. Какие-то узлы после вообще не отрисованы. Спасает свернуть и развернуть узел. TreeView.Repaint не помогает.

2 часа назад, krapotkin сказал:

дерево это визуальное представление какой то модели

если сортировать модель, а в дереве отображать изменения, то проблем не возникнет

Это, конечно метод. Если у пользователя идет работа с деревом, которое он видит и понимает (добавление узлов, их перенос, изменение имен), то после каждого такого единичного и простого действия надо записать дерево в модель, отсортировать ее там, и заново нарисовать дерево... При этом после отрисовки заново сохранить свернутость/развернутость узлов, положение дерева на экране (если оно длинное и не помещается целиком), подсветить выделенные узлы и т.д.

Наверное я очень ленивый ))) Если нет никакого специального флажка где-то, который позволял бы TreeView.Sorted:=true сортировать все узлы на всех уровнях и позволял бы забыть вообще о такой заботе, я выберу сортировать конкретный узел и постараюсь победить визуализацию.

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...