我有一个在VirtualStringTree中显示的数据层次。我在我的应用程序中多次使用此heirarchy,略微修改了绘制/显示树的方式。我的方法目前使用AddChild()过程来添加节点,因此我在运行应用程序时有多个数据副本。
我现在想要整合这些树,并有一个指向实际数据的“主”树,然后让“从属”树指向SAME数据。
我有点不确定是否/如何实现这一点。我想我可以简单地加载主树并用指向我所保存数据的指针填充它的NodeData,然后对于所有从属树,只需将相同的指针存储在它们的nodedata中。
但是我没有太多运气。
我目前的代码如下:
//Initialize the NodeDataSize
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeMasterComponents.NodeDataSize := SizeOf(rMasterComponent);
VST.NodeDataSize := SizeOf(Pointer);
end;
将主树复制到从属树的过程
procedure TForm1.LoadSlaveTree(ATree: TVirtualStringTree);
var Node : PVirtualNode;
procedure RecursiveCopy(SrcPNode,SrcTNode : PVirtualNode; ATree : TVirtualStringTree);
var SrcNode, TargetNode : PVirtualNode;
SrcData : PMasterComponent;
begin
SrcNode := TreeMasterComponents.GetFirstChild(SrcPNode);
while Assigned(SrcNode) do
begin
SrcData := TreeMasterComponents.GetNodeData(SrcNode);
TargetNode := ATree.AddChild(SrcTNode,SrcData);
RecursiveCopy(SrcNode,TargetNode,ATree);
SrcNode := SrcNode.NextSibling;
end;
end;
begin
ATree.BeginUpdate;
ATree.Clear;
Node := TreeMasterComponents.GetFirst(true);
while Assigned(Node) do
begin
RecursiveCopy(Node,nil,ATree);
Node := Node.NextSibling;
end;
ATree.EndUpdate;
end;
从树到getCellText的过程
procedure TForm1.SlaveGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var Data : PMasterComponent;
begin
Data := Sender.GetNodeData(Node);
Case column of
0:CellText := Data^.ComponentCode;
1:CellText := Data^.FullLocation;
end;
end;
目前,节点被添加到正确的层次结构中,但是没有文本出现在从属树上。任何帮助将不胜感激。
答案 0 :(得分:2)
我不知道为什么你的奴隶树上没有文字,但我想建议以下内容。
使用树和代码创建框架可能更容易,并在表单上重用框架。树的每个实例都只是加载相同的数据(不需要复制节点)。
通过为帧/树的特定实例编写新的事件处理程序,可以通过可视化表单继承来实现轻微的修改。如果需要,您也可以从框架继承,创建一个新类。
答案 1 :(得分:2)
好的,所以我相信我找到了解决方案:
诀窍是创建一个新记录来将指针存储到原始数据中:
type PRefMasterComponent = ^RefMasterComponent;
RefMasterComponent = packed record
PMCData : PMasterComponent;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeMasterComponents.NodeDataSize := SizeOf(rMasterComponent);
VST.NodeDataSize := SizeOf(RefMasterComponent);
end;
现在复制代码如下:
procedure TForm1.LoadTree(ATree: TVirtualStringTree);
var Node,TargetNode : PVirtualNode;
SrcData : PMasterComponent;
Data : PRefMasterComponent;
procedure RecursiveCopy(SrcPNode, TargetPNode : PVirtualNode; ATree : TVirtualStringTree);
var Node, TargetNode : PVirtualNode;
SrcData : PMasterComponent;
Data : PRefMasterComponent;
begin
Node := TreeMasterComponents.GetFirstChild(SrcPNode);
while Assigned(Node) do
begin
SrcData := TreeMasterComponents.GetNodeData(Node);
TargetNode := ATree.AddChild(TargetPNode);
Data := ATree.GetNodeData(TargetNode);
Data.PMCData := SrcData;
RecursiveCopy(Node,TargetNode,ATree);
Node := Node.NextSibling;
end;
end;
begin
ATree.BeginUpdate;
ATree.Clear;
Node := TreeMasterComponents.GetFirst(true);
while Assigned(Node) do
begin
SrcData := TreeMasterComponents.GetNodeData(Node);
TargetNode := ATree.AddChild(nil);
Data := ATree.GetNodeData(TargetNode);
Data.PMCData := SrcData;
RecursiveCopy(Node,TargetNode,ATree);
Node := Node.NextSibling;
end;
ATree.EndUpdate;
end;
和OnGetText:
procedure TForm1.vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var Data : PRefMasterComponent;
RefData : PMasterComponent;
begin
Data := Sender.GetNodeData(Node);
RefData := Data.PMCData;
Case column of
0:CellText := RefData.ComponentCode;
1:CellText := RefData.FullLocation;
end;
end;
现在,如果我在一棵树中更改数据,我所要做的就是调用VST.Invalidate并将更改反映在另一棵树中。