2011-10-25 42 views
1

我有一個顯示在VirtualStringTree中的數據的層次結構。我在我的應用程序中多次使用這種層次結構,並對樹的繪製/顯示方式進行了輕微修改。我的方法當前使用AddChild()過程來添加節點,因此在應用程序運行時我有多個數據副本。使用1個數據副本同步多個VirtualStringTrees

我現在想合併這些樹並且有一個指向實際數據的「主」樹,但是然後讓'奴隸'樹指向同一個數據。

我有點不確定是否/如何達到這個目的。我會認爲我可以簡單地加載主樹,並使用指向我所保存的數據的指針來填充它的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; 

目前,節點被添加到正確的層次結構中,但是沒有文本出現在從屬樹中。任何幫助,將不勝感激。

回答

2

行,所以我beleive我已經找到了解決辦法:

訣竅是要建立一個新的記錄到存儲指向原始數據:

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,並將更改反映到另一棵樹中。

+0

從你的問題,我以爲你已經這樣做了。 ;-)恭喜找到解決方案。 –

+0

我想這樣做,只是沒有在那裏! :) – Simon

2

我不知道爲什麼沒有文字出現在您的奴隸樹,但我想建議以下。

可能更容易的是創建一個框架與樹和代碼,並重用您的窗體上的框架。樹的每個實例只會加載相同的數據(不需要複製節點)。

通過爲特定的框架/樹實例編寫新的事件處理程序,可以通過視覺形式繼承來實現輕微的修改。如果需要,您也可以從框架繼承,創建一個新類。

+0

這是(種)我目前如何做,但例如,如果我在一棵樹中更改數據,它不會反映在其他樹中。我已經找到了解決方案,所以我將盡快發佈到 – Simon

+0

如果樹使用的是相同的數據,則只需在數據更改時使樹(或相關節點)無效,以使樹重新繪製自己。如果數據的層次結構發生變化,則需要重新加載樹(或相關節點)。 –