如何将数据分配给InitNode事件中的VirtualStringTree节点
我不知道如何将数据分配给VirtualStringTree中的节点。我需要为树控件的InitNode事件中的Node的Data属性指定一个记录对象的指针。但是,我得到一个'所需的指针类型'编译时错误。如何将数据分配给InitNode事件中的VirtualStringTree节点
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年早期,然后用TList
和存储指针到TDiagData
:
NodeData^ := PDiagData(FDiagDataList[c])^;
如果您使用的Delphi 2009或更高版本,然后用TList<TDiagData>
,然后摆脱类型转换:
NodeData^ := FDiagDataList[c];
无论哪种方式,你可能会发现事情变得更容易管理,如果每事件处理程序开始时以同样的方式,具有GetNodeData
调用获取类型安全点呃到当前节点的数据。
Eeek!那'c'仍然与我们在一起。 – TLama 2014-10-29 17:03:18
那么,@Tlama?我们可以用一些元表达式替换它,*'expression-that-selecting-data-for-current-node' *,但是我们也可以假设*'c' *已经*是这样一个表达式。为什么要说话? – 2014-10-29 17:18:24
@RobKennedy:好,相关答案。 – 2014-10-29 17:36:06
我可以猜到编译器错误是什么,但要说教,请问编辑问题以包含编译器错误。我其实认为你在这里有两个明显的错误。但是你最好告诉我们他们是什么。 – 2014-10-29 14:49:00
'DiagData:= Sender.GetNodeData(Node); DiagData.DiagID:= ...'或'DiagData:= Sender.GetNodeData(Node); DiagData ^:= FDiagDataList.Items [c]'但什么是'c'? – TLama 2014-10-29 14:49:14
@TLama:是的,它的工作原理! – 2014-10-29 14:51:44