Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.237.65.102] |
|
Сообщ.
#1
,
|
|
|
Делаю обход всех узлов TTreeView.
Обнаружил такую вещь, что получить корневые узлы, как дочерние, нельзя. Т.е. сначала нужно взять TopItem, а затем (если он не nil, разумеется) выполнять GetNextSibling, пока не получим nil. Т.е. даже Count узнать нельзя! Ну что за... ?! Неужели нет способа перечислить их как дочерние через for i := 0 to Node.Count-1 do Recurse(Node[i]); ??? |
Сообщ.
#2
,
|
|
|
Цитата Jin X @ Т.е. даже Count узнать нельзя! Ну что за... ?! Это не стена, а дерево, причем виндовое. У него есть единственный хранимый TTreeView.Count - общее кол-во узлов\элементов в дереве. А TTreeNode.Count - это дельфийская примочка для пионЭров\формошлёпов, которые обожают цикл for и избегают while\repeat. Для них дядя Борланд специально написал простенькую функцию TTreeNode.GetCount, которая через GetFirst\NextChild "бы-ыстренько" подсчитывает кол-во дочерних элементов узла, и еще более тупую функцию property Item[i] = GetItem(i), которая также через GetFirst\NextChild находит дочерний элемент по заданному индексу. Вот и подумай - "Оно тебе надА"? Вместо одного собственного цикла while запускать Count+1 аналогичных циклов, упрятанных под капотом свойств Count и Item[i] ?! |
Сообщ.
#3
,
|
|
|
Под капот не заглядывал, но в целом ясно
|
Сообщ.
#4
,
|
|
|
Цитата Jin X @ Делаю обход всех узлов TTreeView. Обнаружил такую вещь, что получить корневые узлы, как дочерние, нельзя. Для обхода всех узлов есть универсальные методы GetNext и GetNextVisible, которые выдают следующий по порядку узел независимо от его уровня. (Если нужен учет уровня, то это можно сделать внутри процедуры обработки по if или case Level). В принципе для последовательного обхода всех узлов дерева можно использовать и св-во TTreeView.Items[i] в цикле for. Хотя в справке и говорится, что это м.б. time-intensive, но на самом деле это относится только к непоследовательному доступу, т.к. в коллекции TTreeNodes используется элементарное кэширование\запоминание последнего индекса и соотв-го ему узла, поэтому при изменении индекса на +-1 используются те же GetNext или GetPrev относительно предыдущего узла. В общем же случае приходится крутить цикл поиска элемента по индексу через GetNext аналогично св-ву TTreeNode.Item[i]. Отсюда и can be time-intensive. |
Сообщ.
#5
,
|
|
|
leo, да, мне с учётом уровня и надо было как раз.
Ну а если брать родителя через GetNextSibling, а предков через Items (рекурсивно), в принципе, тоже последовательно должно быть. Тогда тоже не должно быть time-intensive, получается? Хотя, конечно, через GetNext с проверкой Level проще. Не знал просто раньше, что есть Level. Так-то, действительно, проще получается... |
Сообщ.
#6
,
|
|
|
Ну и если немножко побурчать: обходить надо не TreeView, а ту модель данных, на основании которой TreeView заполняется. Не будет никаких шараханий по WinAPI, можно делать это из другого потока - в общем, сплошные плюсы
|
Сообщ.
#7
,
|
|
|
Цитата Mr.Delphist @ Ты имеешь в виду другое "хранилище" данных (древовидный список вне TTreeView). Это понятно, но и к TTreeView эти данные нужно же привязать тоже. Да, можно привязать, например, к Data, но тогда поиск TTreeNode с нужным Data будет тоже долгим... Ну и если немножко побурчать: обходить надо не TreeView, а ту модель данных, на основании которой TreeView заполняется. |
Сообщ.
#8
,
|
|
|
Я про подход в стиле MVVM, MVC и т.п. Когда TreeView - не более чем отображалка, её можно убрать или изменить, но код обработки данных от этого НЕ изменится.
|