i.r.khayrullin Опубликовано 10 февраля, 2016 Опубликовано 10 февраля, 2016 Добрый день! Пытаюсь отсортировать элементы дерева таким образом: procedure TForm1.SortTreeItemsClick(Sender: TObject); begin TreeView1.Sort(MySortTree); TreeView1.RealignContent; end; Элементы дерева приводятся на свое место, но их отображение прекращается. Некоторые элементы видны как фантомы, некоторые - пустые строки. Перепробовал всё, пытаясь обновить дерево, ничего не удалось. Демка во вложении, там есть работающий вариант с ListBox. TestingSort.zip Цитата
0 enatechno Опубликовано 11 февраля, 2016 Опубликовано 11 февраля, 2016 (изменено) По приложенному примеру: в MySortTree нужно TTreeViewItem вместо TListBoxItem. при работе с 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 для автоматической сортировки в алфавитном порядке по тексту в айтемах. Изменено 12 февраля, 2016 пользователем Brovin Yaroslav i.r.khayrullin и Kitty 2 Цитата
0 i.r.khayrullin Опубликовано 11 февраля, 2016 Автор Опубликовано 11 февраля, 2016 Да, ошибка вышла, торопился написать пример. В рабочем проекте, конечно никаких ListBoxItem небыло. Спасибо, обычно использую. Просто старался минимизировать пример, что бы найти проблему методом "проб". Пробовал и том числе и 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 Администраторы Brovin Yaroslav Опубликовано 12 февраля, 2016 Администраторы Опубликовано 12 февраля, 2016 Выравнивать итемы заставляет метод EndUpdate. Но только, если были внутри секции BeginUpdate/EndUpdate были изменения требующие выравнивания. Если хотите форсировать выравнивание, это можно сделать так: (TreeView1 as IAlignRoot).Realign; Цитата
0 Администраторы Brovin Yaroslav Опубликовано 12 февраля, 2016 Администраторы Опубликовано 12 февраля, 2016 Чтобы отсортировать TTreeView нужно делать так: Устанавливаете свойство TTreeView.Sorted = True Задаем обработчик сравнения TTreeView.OnCompare. Kitty 1 Цитата
0 Frol Опубликовано 8 июня Опубликовано 8 июня (изменено) В 12.02.2016 в 20:11, Brovin Yaroslav сказал: Чтобы отсортировать TTreeView нужно делать так: Устанавливаете свойство TTreeView.Sorted = True Задаем обработчик сравнения 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. Этот блок перемещает все узлы в самый первый. Если оставить несколько узлов в корне, то процедура сортировки вызывается, но сортирует только верхний уровень. вложенные уровни не сортируются. Как быть с сортировкой внутри веток? Изменено 8 июня пользователем Frol Цитата
0 krapotkin Опубликовано Вторник в 06:22 Опубликовано Вторник в 06:22 дерево это визуальное представление какой то модели если сортировать модель, а в дереве отображать изменения, то проблем не возникнет Цитата
0 Frol Опубликовано Вторник в 09:34 Опубликовано Вторник в 09:34 Эксперименты показали, что TreeView.Sorted:=true сортирует только верхний уровень. Каждый вложенный узел надо сортировать через TreeViewItem.Sort(). При этом могут возникать дефекты визуализации. Какие-то узлы после вообще не отрисованы. Спасает свернуть и развернуть узел. TreeView.Repaint не помогает. 2 часа назад, krapotkin сказал: дерево это визуальное представление какой то модели если сортировать модель, а в дереве отображать изменения, то проблем не возникнет Это, конечно метод. Если у пользователя идет работа с деревом, которое он видит и понимает (добавление узлов, их перенос, изменение имен), то после каждого такого единичного и простого действия надо записать дерево в модель, отсортировать ее там, и заново нарисовать дерево... При этом после отрисовки заново сохранить свернутость/развернутость узлов, положение дерева на экране (если оно длинное и не помещается целиком), подсветить выделенные узлы и т.д. Наверное я очень ленивый ))) Если нет никакого специального флажка где-то, который позволял бы TreeView.Sorted:=true сортировать все узлы на всех уровнях и позволял бы забыть вообще о такой заботе, я выберу сортировать конкретный узел и постараюсь победить визуализацию. Цитата
Вопрос
i.r.khayrullin
Добрый день!
Пытаюсь отсортировать элементы дерева таким образом:
Элементы дерева приводятся на свое место, но их отображение прекращается. Некоторые элементы видны как фантомы, некоторые - пустые строки.
Перепробовал всё, пытаясь обновить дерево, ничего не удалось. Демка во вложении, там есть работающий вариант с ListBox.
TestingSort.zip
7 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.