Вопрос, который стоит перед разработчиком, заключается в необходимости заполнения компонента TTreeView из среды разработки Delphi на основе плоского списка объектов, каждый из которых имеет свой уровень иерархии. В данном случае, вместо использования стандартного свойства Parent, применяется свойство Level, которое указывает на уровень вложенности элемента в дереве.
Описание проблемы
У вас есть список объектов, загруженный из файла третьей стороны, где каждый элемент имеет свой уровень иерархии. Ваша задача состоит в том, чтобы заполнить TTreeView на основе этих уровней, не используя свойство родителя.
Для решения этой задачи можно использовать дополнительный список, который будет содержать ссылку на последний добавленный узел для каждого уровня. Изначально этот список будет пустым. Затем, при итерации по плоскому списку, каждый новый элемент добавляется как дочерний узел последнего добавленного узла на предыдущем уровне. После добавления элемента, текущий последний добавленный узел для его уровня обновляется.
В случае, если уровень элемента равен 0, предполагается, что существует корневой узел дерева, иначе необходимо добавить элемент на верхнем уровне дерева.
Пример кода
var
Item: TMyItem;
Node: TTreeNode;
LatestNodes: TArray<TTreeNode>;
Parent, NewNode: TTreeNode;
begin
SetLength(LatestNodes, 0);
LatestNodes := TArray<TreeNode>.Create(MyList.MaxLevel);
try
for var X := 0 to High(LatestNodes) do
LatestNodes[X] := nil;
for X := 0 to MyList.Count - 1 do
begin
Item := MyList[X];
Parent := LatestNodes[Item.Level];
NewNode := TreeView1.Items.AddChildObject(Parent, Item.Title, Item);
LatestNodes[Item.Level] := NewNode;
if LatestNodes.Length < Item.Level + 1 then
LatestNodes.Add(nil);
end;
finally
LatestNodes.Free;
end;
end;
Оптимизированный подход
Для упрощения кода и повышения его эффективности можно использовать следующий подход:
var
Item: TMyItem;
Node: TTreeNode;
NodeLevel: Integer;
begin
Node := nil;
NodeLevel := -1; // Предполагаем, что у нас есть корневой узел
for X := 0 to MyList.Count - 1 do
begin
Item := MyList[X];
while Item.Level <= NodeLevel do
begin
Node := Node.Parent;
Dec(NodeLevel);
end;
Node := TreeView1.Items.AddChildObject(Node, Item.Title, Item);
while NodeLevel < Item.Level do
begin
Node := Node.LastChild;
Inc(NodeLevel);
end;
end;
end;
Этот код использует свойство Level объекта для определения иерархического положения узла, не требуя дополнительных структур данных для хранения родительских узлов.
Заключение
Приведенные примеры кода демонстрируют, как можно заполнить TTreeView на основе плоского списка объектов, используя свойство уровня. Это может быть полезно, когда структура данных не позволяет использовать стандартные связи родитель-потомок.
Задача заключается в преобразовании плоского списка объектов в иерархическое дерево для компонента TTreeView в Delphi, используя свойство уровня, а не родителя.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.