gpt4 book ai didi

delphi - VirtualStringTree - 使用对象时添加/处理子节点/子节点的正确方法?

转载 作者:行者123 更新时间:2023-12-03 15:08:40 34 4
gpt4 key购买 nike

我正在使用 Delphi2010 并尝试使用 VirtualStringTree。

我一直在尝试让它与对象一起工作,但一直没有运气,直到我遵循了 Philipp Frenzel 的 Virtual TreeView 教程(我在 soft-gems.net 网站上找到了该教程)。到目前为止我所想出的方法是有效的,但我认为我没有正确处理子节点(即子节点)。

我唯一能做的就是为每个 child 再次链接整个对象,然后只显示我需要的字段 - 但感觉太不对劲了。

非常感谢建议/反馈。

<小时/>

我有一个对象列表,我试图与 VirtualStringTree 连接,我试图实现这样的目标,其中一个字段将充当父节点的标签,其余字段显示为子节点。

  • 罗伯特·莱恩
    • 35
    • 洛杉矶
    • 黑发
  • 简·多伊
    • 女性
    • 19
    • 丹佛
    • 红发女郎

这就是我的类(class)的设置方式。

type
PTreeData = ^TTreeData;
TTreeData = record
FObject : TObject;
end;

TCustomerNode = class(TObject)
private
fName: string;
fSex: string;
fAge: integer;
fHair: string;
//...
public
property Name: string read fName write fName;
//...
end;

填充对象后,我将它们添加到基于 TList 的另一个类 (CustomerObjectList),如下所述。

这是我将 VirtualStringTree 与对象列表连接的位置

procedure TfrmMain.btnLoadDataClick(Sender: TObject);
var
i, j : integer;
CustomerDataObject: TCustomerNode;
RootXNode, XNode: PVirtualNode;
Data: PTreeData;
begin
vstree.NodeDataSize := SizeOf( TTreeData );

vstree.BeginUpdate;
for i := 0 to CustomerObjectList.Count - 1 do
begin
CustomerDataObject := CustomerObjectList[i];

//load data for parent node
RootXNode := vstree.AddChild(nil);
Data := vstree.GetNodeData(RootXNode);
Data^.FObject:= PINodeSource;

//now add children for rest of fields
//Isn't there a better way to do this?
for j := 1 to NUMBERofFIELDS -1 do //first field is label for parent so -1
begin
XNode := vstree.AddChild(RootXNode);
Data := vstree.GetNodeData(XNode);
Data^.FObject:= PINodeSource;
end;

end;
vstree.EndUpdate;
end;

procedure TfrmMain.vstreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
Data : PTreeData;
begin
Data := vstObjects.GetNodeData(Node);
////if Node.ChildCount = 0 then //edit - oops typo!
if Node.ChildCount > 0 then
begin
CellText := TCustomerNode(Data.FObject).Name;
exit;
end;

//handle childnodes
case Node.Index of
0: CellText := TCustomerNode(Data.FObject).Sex;
1: CellText := IntToStr(TCustomerNode(Data.FObject).Age);
2: CellText := TCustomerNode(Data.FObject).Hair;
3: CellText := TCustomerNode(Data.FObject).City;
end;
end;

最佳答案

您不需要将所有数据加载到树中。您可以利用树的“虚拟性”。这是我的做法。

将树的 RootNodeCount 设置为 CustomerObjectList 中的记录数:

vstree.RootNodeCount := CustomerObjectList.Count;

然后,在 OnInitChildren 事件中,将 0 级节点的子节点数设置为您要显示的属性数量:

procedure TfrmMain.vstreeInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
if Sender.GetNodeLevel(Node) = 0 then
begin
Sender.ChildCount[Node] := 4;

// Comment this out if you don't want the nodes to be initially expanded
Sender.Expanded[Node] := TRUE;
end;
end;

现在,只需在 OnGetText 事件中检索正确的数据即可。

procedure TfrmMain.vstreeGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
begin
if Column <= 0 then
begin
if Sender.GetNodeLevel(Node) = 0 then
CellText := CustomerObjectList[Node.Index].Name else
if Sender.GetNodeLevel(Node) = 1 then
begin
case Node.Index of
0: CellText := CustomerObjectList[Parent.Node.Index].Sex;
1: CellText := CustomerObjectList[Parent.Node.Index].Age;
2: CellText := CustomerObjectList[Parent.Node.Index].Hair;
3: CellText := CustomerObjectList[Parent.Node.Index].City;
end; // of case
end;
end;

您可能需要添加更多范围检查,以防万一。

希望这有帮助。

关于delphi - VirtualStringTree - 使用对象时添加/处理子节点/子节点的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8005452/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com