When working with TVirtualStringTree in Delphi, you might encounter issues when rendering parent-child nodes, especially when the data is fetched from datasets. This article aims to guide you through the correct approach to render parent-child nodes in a TVirtualStringTree control.
The Problem
The original problem is about rendering a main menu in a TVirtualStringTree, where each menu item belongs to a category. The categories should make up the root nodes of the tree, and under each category root node, the menu items should be rendered as child nodes. However, the user encountered an issue where all category nodes displayed the same text, indicating that the dataset was not scrolling to the next record.
Upon investigation, it was found that the line of code Sender.ChildCount[Node] := x; in the InitNode event was causing the loop to exit prematurely, leading to incorrect rendering of the child nodes.
The Solution
To correctly render parent-child nodes in a TVirtualStringTree, follow these steps:
Create separate procedures for adding nodes: Instead of initializing nodes within the InitNode event, create separate procedures for adding parent and child nodes to the tree. This approach ensures that the nodes are added in the correct order and prevents premature exit from the loop.
Here's an example of how to create parent nodes in a separate procedure:
procedure TfrmMain.AddCategoryNodes;
var
LTreeCategoryData: PTreeCategoryData;
LCategoryNode: PVirtualNode;
begin
datamod.uspspmenucatgy_S.PrepareSQL(True);
datamod.uspspmenucatgy_S.Open;
while not datamod.uspspmenucatgy_S.Eof do
begin
// 1. create parent node itself
LTreeCategoryData := New(PTreeCategoryData);
with LTreeCategoryData^ do
begin
ID := datamod.uspspmenucatgy_Srow_id.AsInteger;
DispText := datamod.uspspmenucatgy_Scategory.AsString;
end;
LCategoryNode := vstmainmenu.AddChild(vstmainmenu.RootNode, LTreeCategoryData);
// 2. create child nodes (menu items)
AddMenuItems(LCategoryNode, datamod.uspspmenucatgy_Srow_id.AsInteger);
datamod.uspspmenucatgy_S.Next;
end;
datamod.uspspmenucatgy_S.Close;
end;
And here's an example of how to create child nodes (menu items) in a separate procedure:
procedure TfrmMain.AddMenuItems(CategoryNode: PVirtualNode; CategoryID: Integer);
var
LTreeMenuItemData: PTreeMenuItemData;
begin
datamod.uspspmenu_S.ParamByName('Pcategory_id').AsInteger := CategoryID;
datamod.uspspmenu_S.PrepareSQL(True);
datamod.uspspmenu_S.Open;
while not datamod.uspspmenu_S.Eof do
begin
LTreeMenuItemData := New(PTreeMenuItemData);
with LTreeMenuItemData^ do
begin
ID := datamod.uspspmenu_Srow_id.AsInteger;
CategoryID := datamod.uspspmenucatgy_Srow_id.AsInteger;
DispText := datamod.uspspmenu_Smenuitem.AsString;
ClassName := datamod.uspspmenu_Stframeclass.AsString;
end;
vstmainmenu.AddChild(CategoryNode, LTreeMenuItemData);
datamod.uspspmenu_S.Next;
end;
datamod.uspspmenu_S.Close;
end;
Call the procedures to add nodes: In the FormShow event or any other event where you want to load the tree, call the procedures responsible for adding nodes to the tree. For example:
procedure TfrmMain.FormShow(Sender: TObject);
begin
AddCategoryNodes;
end;
Conclusion
By creating separate procedures for adding parent and child nodes to the TVirtualStringTree and calling these procedures when needed, you can ensure that the nodes are rendered correctly. This approach prevents premature exit from the loop and ensures that the dataset is traversed correctly, resulting in the correct display of parent-child nodes in the tree.
In this article, we've discussed the problem of rendering parent-child nodes in a TVirtualStringTree and provided a step-by-step solution to correctly render the nodes. By following the guidelines outlined in this article, you should be able to render parent-child nodes in a TVirtualStringTree without encountering the issues described in the original problem.
Статья о правильном отображении родительских и дочерних узлов в TVirtualStringTree в Delphi, с акцентом на решении проблемы, связанной с неправильным отображением дочерних узлов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS