仕組みを少し掘り下げてみましたCopyTo()
。コピーするすべてのノードは最初にストリームに保存され、次にストリームのノードがターゲット VirtualTree で再作成されます。ユーザー ノード データをそのストリームにコピーする必要があります。そうしないと、ターゲット VirtualTree でノードを再作成するときに使用できなくなります。
ストリーミング ユーザー データを処理するイベントは次のとおりです。
VirtualTree がこれらのメソッドを利用することは理にかなっており、結果として、ストリームを中間オブジェクトとして使用することは理にかなっています。VirtualTree を使用すると、ツリーをファイルに保存したり、ノードをクリップボードにコピーして貼り付けたりすることもできます。これらのメソッドはすべて、何らかの方法でユーザーの「ペイロード」をコピーする必要があります! これらのイベントを実装した後、CopyTo
メソッドは正常に機能し、最初のツリーのコンテンツをディスクに保存して、2 番目のツリーに再ロードしました。コピー&ペーストもテストしましたが、うまくいきました。
OnSaveNode
これがとの私の実装ですOnLoadNode
。ノード ペイロードに入れるデータの種類に依存するため、私のメソッドをコピーして貼り付けてもうまくいかない可能性があります。私の例では、1 つの整数のみで構成されるレコード (レコードへのポインターではなく) を配置しました。これらのレコードは、安全にディスクにストリーミングして再読み込みできます。それらはマネージド型ではなく、単純な値型です。レコードにポインターを配置している場合 (レコードへの参照)、これを引き続き使用でき、機能しますが、ポインターをコピーすることになります: 新しいレコードは取得されません。同じ記録; 明らかに、ツリーをファイルに保存したり、プログラムを再起動したり、ディスクからリロードしたりすることはできません。
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;
最後に 1 つ: あなたのシナリオOnSaveNode
では、ソース ツリーに をOnLoadNode
実装し、ターゲット ツリーに を実装する必要があります。同じコードを使用して両方に実装しました。