我不确定如何将数据分配给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事件中将数据分配给节点,但不确定如何分配它。
答案 0 :(得分:2)
不要直接读或写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
,但您清楚地存储了不是<{1}}的后代的内容。如果您不使用对象,请不要使用TObject
。如果您在2009年之前使用的是Delphi版本,请使用TObjectList
并将指针存储到TList
:
TDiagData
如果您正在使用Delphi 2009或更高版本,请使用NodeData^ := PDiagData(FDiagDataList[c])^;
,然后摆脱类型转换:
TList<TDiagData>
无论哪种方式,如果每个事件处理程序以相同的方式启动,并且调用NodeData^ := FDiagDataList[c];
来获取类型安全指针,您可能会发现更容易管理的事情到当前节点的数据。