VirtualTreeView复制带有数据的树 [英] VirtualTreeView copy tree with data

查看:187
本文介绍了VirtualTreeView复制带有数据的树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将所有节点从一个VirtualTreeView复制到另一个? 我尝试使用CopyTo-function,但是数据为空,为什么? 数据包含对记录的引用(与往常一样).

How to copy all nodes from one VirtualTreeView to another? I tried to use CopyTo-function, but the Data was empty, why? Data contains reference to record (as usual).

我还尝试使用@csmin Prund在他现在已删除的答案中建议的OnNodeCopying事件,但是会崩溃:

I've also tried to use the OnNodeCopying event as @Cosmin Prund suggested in his now deleted answer this way, but it crashes:

procedure TDataBaseForm.SourceTreeViewNodeCopying(Sender: TBaseVirtualTree; 
  Node, Target: PVirtualNode; var Allowed: Boolean); 
var 
  SourceNodeData, DestNodeData: PNodeDataForCompare; 
begin 
  SourceNodeData := Sender.GetNodeData(Node); 
  DestNodeData := VirtualStringTree1.GetNodeData(Target); 
  if Assigned(SourceNodeData) then 
  begin 
    DestNodeData^ := SourceNodeData^; 
  end; 
  Allowed := true; 
end;

推荐答案

我已经对CopyTo()的工作方式进行了更深入的研究.首先将所有要复制的节点保存到流中,然后在目标VirtualTree上重新创建该流中的节点.用户节点数据需要复制到该流中,否则在目标VirtualTree中重新创建节点时将不可用.

I've dug a bit deeper into how the CopyTo() works. All the nodes to be copied are first saved to a stream, next the nodes from the stream are re-created on the target VirtualTree. The user node data needs to be copied into that stream, or else it will not be available when re-creating the nodes in the target VirtualTree.

处理流用户数据的事件是:

The events that handle streaming user data are:

  • OnSaveNode
  • OnLoadNode

VirtualTree使用这些方法很有意义,因此使用流作为中介对象也很有意义. VirtualTree还允许将树保存到文件,以及将节点复制粘贴到剪贴板和从剪贴板复制节点.所有这些方法都需要以某种方式复制用户的有效载荷"!在实现这些事件之后,CopyTo方法可以正常工作,将第一棵树的内容保存到磁盘并将其重新加载到第二棵树中也可以.我还测试了复制粘贴,并且效果很好.

It makes sense for the VirtualTree to make use of those methods, and as a consequence makes sense to use the stream as an intermediary object. The VirtualTree also allows saving the tree to a file and copy-pasting nodes to and from clipboard. All those methods need to somehow copy the user's "payload"! After implementing those events the CopyTo method worked fine, so did saving the the content of the first tree to disk and re-loading it into the second tree. I also tested copy-pasting and it worked fine.

这是我对OnSaveNodeOnLoadNode的实现.复制粘贴我的方法很可能对您不起作用,因为它取决于您放入节点有效负载中的数据类型.在我的示例中,我放置了仅由一个Integer组成的记录(而不是指向记录的指针):这些记录可以安全地流式传输到磁盘并重新加载,它们不是托管类型,它们是简单的值类型.如果将指针放置到记录中(称为记录的引用),您仍然可以使用它并且可以使用,但是您将复制POINTERS:您没有获得新记录,它们就是相同的记录;您显然无法将Tree保存到文件,重新启动程序并从磁盘重新加载.

Here's my implementation of the OnSaveNode and OnLoadNode. Copy-pasting my methods will most likely not work for you, because it depends on the kind of data you put in the node payload. In my example I placed records (not pointers-to-records) made up of just one Integer: those records can safely be streamed to disk and reloaded, they're not managed types, they're simple value types. If you're placing pointers into the records (reference-to-records as you called them) you can still use this and it will work, but you'd be copying POINTERS: You don't get new records, they're the same records; you obviously can't save the Tree to a file, restart the program and reload from disk.

procedure TForm6.VT1SaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
begin
  Stream.Write(Sender.GetNodeData(Node)^, (Sender as TVirtualStringTree).NodeDataSize);
end;

procedure TForm6.VT2GetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
begin
  CellText := IntToStr(PNodeDataForCompare(VT1.GetNodeData(Node)).Payload);
end;

最后一点:对于您的场景,您需要在Source树上实现OnSaveNode和在Target树上实现OnLoadNode;我使用相同的代码在两者上实现了它们.

One final note: For your scenario you'll need the OnSaveNode implemented on the Source tree and the OnLoadNode implemented on the Target tree; I implemented them on both using the same code.

这篇关于VirtualTreeView复制带有数据的树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆