0

ある VirtualTreeView から別の VirtualTreeView にすべてのノードをコピーする方法は? CopyTo 関数を使用しようとしましたが、データが空でした。なぜですか? データにはレコードへの参照が含まれています (通常どおり)。

OnNodeCopying@Cosmin Prund が削除された回答でこのように提案したように、イベントを使用しようとしましたが、クラッシュします。

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;
4

2 に答える 2

5

仕組みを少し掘り下げてみましたCopyTo()。コピーするすべてのノードは最初にストリームに保存され、次にストリームのノードがターゲット VirtualTree で再作成されます。ユーザー ノード データをそのストリームにコピーする必要があります。そうしないと、ターゲット VirtualTree でノードを再作成するときに使用できなくなります。

ストリーミング ユーザー データを処理するイベントは次のとおりです。

  • OnSaveNode
  • OnLoadNode

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実装し、ターゲット ツリーに を実装する必要があります。同じコードを使用して両方に実装しました。

于 2013-02-16T12:11:24.370 に答える
0
unit VirtualTrees;

...

function TBaseVirtualTree.CopyTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean): PVirtualNode;

...

        Result := TargetTree.MakeNewNode;
        InternalConnectNode(Result, Target, TargetTree, Mode);
        TargetTree.InternalAddFromStream(Stream, VTTreeStreamVersion, Result);
        if not DoNodeCopying(Result, Source {Target}) then //        <=======
        begin
          TargetTree.DeleteNode(Result);
          Result := nil;
        end

...

于 2013-11-21T11:00:35.530 に答える