1

VirtualStringTreeに表示されるデータの階層があります。私はこの階層をアプリケーションで複数回使用していますが、ツリーの描画/表示方法にわずかな変更を加えています。私のメソッドは現在、AddChild()プロシージャを使用してノードを追加しているため、アプリケーションの実行時にデータの複数のコピーがあります。

これらのツリーを統合し、実際のデータを指す「マスター」ツリーを作成しますが、「スレーブ」ツリーは同じデータを指すようにします。

これを達成できるかどうか/どのように達成できるかは少しわかりません。マスターツリーをロードして、そのNodeDataに、保持しているデータの場所へのポインターを入力し、すべてのスレーブツリーについて、同じポインターをノードデータに格納するだけでよいと思います。

しかし、私はあまり運がありません。

私の現在のコードは次のようになります:

//Initialize the NodeDataSize
procedure TForm1.FormCreate(Sender: TObject);
begin
     TreeMasterComponents.NodeDataSize := SizeOf(rMasterComponent);
     VST.NodeDataSize := SizeOf(Pointer);
end;

マスターツリーをスレーブツリーにコピーする手順

procedure TForm1.LoadSlaveTree(ATree: TVirtualStringTree);
var Node : PVirtualNode;

procedure RecursiveCopy(SrcPNode,SrcTNode : PVirtualNode; ATree : TVirtualStringTree);
var SrcNode, TargetNode : PVirtualNode;
SrcData : PMasterComponent;
begin
     SrcNode := TreeMasterComponents.GetFirstChild(SrcPNode);
     while Assigned(SrcNode) do
     begin
          SrcData := TreeMasterComponents.GetNodeData(SrcNode);
          TargetNode := ATree.AddChild(SrcTNode,SrcData);
          RecursiveCopy(SrcNode,TargetNode,ATree);
          SrcNode := SrcNode.NextSibling;
     end;
end;

begin
     ATree.BeginUpdate;
     ATree.Clear;
     Node := TreeMasterComponents.GetFirst(true);
     while Assigned(Node) do
     begin
         RecursiveCopy(Node,nil,ATree);
         Node := Node.NextSibling;
     end;
     ATree.EndUpdate;
end;

スレーブツリーがgetCellTextを取得するための手順

procedure TForm1.SlaveGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var Data : PMasterComponent;
begin
     Data := Sender.GetNodeData(Node);
     Case column of
     0:CellText := Data^.ComponentCode;
     1:CellText := Data^.FullLocation;
     end;
end;

現時点では、ノードは正しい階層に追加されていますが、スレーブツリーのテキストは表示されていません。どんな助けでもいただければ幸いです。

4

2 に答える 2

2

スレーブツリーにテキストが表示されない理由はわかりませんが、次のことをお勧めします。

おそらく、ツリーとコードを使用してフレームを作成し、フォームでフレームを再利用する方が簡単です。ツリーの各インスタンスは、同じデータをロードするだけです(ノードのコピーは必要ありません)。

フレーム/ツリーの特定のインスタンスに対して新しいイベントハンドラーを作成することにより、視覚的なフォームの継承によってわずかな変更を行うことができます。必要に応じて、フレームから継承して新しいクラスを作成することもできます。

于 2011-10-25T06:47:09.257 に答える
2

わかりました、私は解決策を見つけたと信じています:

秘訣は、ポインタを元のデータに保存するための新しいレコードを作成することでした。

type PRefMasterComponent = ^RefMasterComponent;
  RefMasterComponent = packed record
     PMCData : PMasterComponent;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     TreeMasterComponents.NodeDataSize := SizeOf(rMasterComponent);
     VST.NodeDataSize := SizeOf(RefMasterComponent);
end;

これで、コピーコードは次のようになります。

procedure TForm1.LoadTree(ATree: TVirtualStringTree);
var Node,TargetNode : PVirtualNode;
SrcData : PMasterComponent;
Data : PRefMasterComponent;

procedure RecursiveCopy(SrcPNode, TargetPNode : PVirtualNode; ATree : TVirtualStringTree);
var Node, TargetNode : PVirtualNode;
SrcData : PMasterComponent;
Data : PRefMasterComponent;
begin
     Node := TreeMasterComponents.GetFirstChild(SrcPNode);
     while Assigned(Node) do
     begin
          SrcData := TreeMasterComponents.GetNodeData(Node);
          TargetNode := ATree.AddChild(TargetPNode);
          Data := ATree.GetNodeData(TargetNode);
          Data.PMCData := SrcData;
          RecursiveCopy(Node,TargetNode,ATree);
          Node := Node.NextSibling;
     end;
end;

begin
     ATree.BeginUpdate;
     ATree.Clear;
     Node := TreeMasterComponents.GetFirst(true);
     while Assigned(Node) do
     begin
          SrcData := TreeMasterComponents.GetNodeData(Node);
          TargetNode := ATree.AddChild(nil);
          Data := ATree.GetNodeData(TargetNode);
          Data.PMCData := SrcData;
          RecursiveCopy(Node,TargetNode,ATree);
          Node := Node.NextSibling;
     end;
     ATree.EndUpdate;
end;

およびOnGetText:

procedure TForm1.vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var Data : PRefMasterComponent;
RefData : PMasterComponent;
begin
     Data := Sender.GetNodeData(Node);
     RefData := Data.PMCData;
     Case column of
     0:CellText := RefData.ComponentCode;
     1:CellText := RefData.FullLocation;
     end;
end;

これで、一方のツリーのデータを変更した場合、VST.Invalidateを呼び出すだけで、変更がもう一方のツリーに反映されます。

于 2011-10-25T06:56:00.697 に答える