如何在InitNode事件中将数据分配给VirtualStringTree的节点
我不知道如何将数据分配给VirtualStringTree中的节点。 我需要为树控件的InitNode事件中的Node的Data属性指定一个记录对象的指针。 但是,我得到一个'所需的指针类型'编译时错误。
type
TDiagData = record
DiagID: Integer;
DiagName: String;
Selected: Byte;
end;
PDiagData = ^TDiagData;
var
FDiagDataList: TObjectList;
c: Integer; // used as an iterator for the list // incremented in vst1InitNode
procedure Btn1Click;
var
DiagData : PDiagData;
begin
try
FDiagDataList := TObjectList.Create; // TODO: Move this to form constructor
for c := 1 to 10 do
begin
New(DiagData);
DiagData.DiagID := c;
DiagData.DiagName := Format('Diag# %d', [c]);
FDiagDataList.Add(DiagData);
end;
c := 0;
vst1.NodeDataSize := SizeOf(TDiagData);
vst1.RootNodeCount := 10; // test
finally
// FDiagDataList.Free; //TODO: Move this to form destructor
end
end;
procedure vst1InitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
var
DiagData: PDiagData;
begin
DiagData = TDiagData(FDiagDataList.Items[c]); // FDiagDataList is a TObjectlist
Node.Data^ := DiagData; // <--- this is not working ..
// The error is: Pointer type required.
Inc(c);
end;
我需要将数据分配给InitNode事件中的节点,但不知道如何分配它。
不要直接读取或写入Node.Data
。 您需要的数据不一定会在该字段的地址上。 (树控件有一个允许后代为自己保留额外数据的机制。)相反,调用Sender.GetNodeData
。
var
NodeData: PDiagData;
begin
NodeData := Sender.GetNodeData(Node);
NodeData^ := TDiagData(FDiagDataList.Items[c]);
end;
你的代码失败,因为Node.Data
有类型record
; 你不能用^
来解除引用。 在简单情况下, GetNodeData
返回的值将等于该字段的地址(即, GetNodeData(Node) = @Node.Data
)。 但不要以为所有情况都很简单。 正如我所说的,树控后裔可以保留自己的数据空间,因此您可以使用不受您控制的代码来共享该空间,并由树控制来管理您的数据空间。 始终调用GetNodeData
。
此外,你对你的数据类型感到困惑。 你说FDiagDataList
是一个TObjectList
,但你明确地存储了它不是TObject
的后代的东西。 当你不使用对象时,不要使用TObjectList
。 如果您使用的是早于2009年的Delphi版本,请使用TList
并将指针存储到TDiagData
:
NodeData^ := PDiagData(FDiagDataList[c])^;
如果您使用的是Delphi 2009或更高版本,请使用TList<TDiagData>
,然后摆脱类型转换:
NodeData^ := FDiagDataList[c];
无论哪种方式,如果每个事件处理程序以相同的方式启动,您可能会发现更容易管理的事情,并调用GetNodeData
来获取指向当前节点数据的类型安全指针。
上一篇: How to assign data to node of VirtualStringTree in InitNode event