2011-09-12 33 views
3

我正在嘗試使用VirtualStringTree組件實現一個簡單的聯繫人管理器。我有它設置看起來像一個列表視圖組件只有三列,將所有包含文本:如何保存並加載我的svTree數據結構?

Layout

對於數據結構,我使用svTree由利納,這是在其他堆棧提到溢出問題。

我宣佈這樣的記錄:

type 
    TMainData = record 
    Name, Email, Password: string; 
    end; 

在窗體的OnCreate我有這樣的:

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    MyTree := TSVTree<TMainData>.Create(False); 
    MyTree.VirtualTree := vst1; 
end; 

我從TEdits添加數據是這樣的:

procedure TForm1.BuildStructure; 
var 
    svNode: TSVTreeNode<TMainData>; 
    Data: TMainData; 
begin 
    MyTree.BeginUpdate; 
    try 
    Data.Name := edtname.Text; 
    Data.Email := edtEmail.Text; 
    Data.Password := edtPassword.Text; 
    svNode := MyTree.AddChild(nil, Data); 
    finally 
    MyTree.EndUpdate; 
    end; 
    Label1.Caption := 'Count: '+IntToStr(MyTree.TotalCount); 
end; 

如何將其保存到要加載的流或文件中?我曾嘗試使用MyTree.SaveToFile('C:/Test.dat')MyTree.LoadFromFile('C:/Test.dat'),但是當它加載回來時,樹視圖中不包含任何數據,只有一個空行。

回答

3

您需要設置OnLoadNode和爲貴TSVTree OnSaveNode程序並在這裏實現你的邏輯。您可以查看演示文件夾中的Project2。例如: -

uses 
    uSvHelpers; 

MyTree.OnSaveNode := DoSave; 
MyTree.OnLoadNode := DoLoad; 

procedure TForm1.DoLoad(Sender: TSVTree<TMainData>; Node: TSVTreeNode<TMainData>; Stream: TStream); 
var 
    obj: TMainData; 
begin 
    // 
    if Assigned(Node) then 
    begin 
    //read from stream 
    //read in correct order 
    obj.Name := Stream.AsString; 
    obj.Email := Stream.AsString; 
    obj.Password := Stream.AsString; 
    Node.FValue := obj; 
    end; 
end; 

procedure TForm1.DoSave(Sender: TSVTree<TMainData>; Node: TSVTreeNode<TMainData>; Stream: TStream); 
begin 
    if Assigned(Node) then 
    begin 
    //read from stream 
    Stream.WriteString(Node.FValue.Name); 
    Stream.WriteString(Node.FValue.Email); 
    Stream.WriteString(Node.FValue.Password); 
    end; 
end; 

之後,你可以叫MyTree.SaveToFile('C:/Test.dat')MyTree.LoadFromFile('C:/Test.dat')。在我的演示和這個例子中,我使用了另一個單元(uSvHelpers),它實現了TStream助手以獲得更多的OO流支持。您當然可以使用自己的方式將數據信息寫入流中。

+0

非常感謝你,我現在就開始工作,並且看到我錯過了什麼。我試圖這樣做「有點」,但是在'Stream.WriteString'部分,我使用了+運算符來將它們組合在一起!衛生署! - 我使用你的答案唯一的問題是一個不兼容的類型與:'如果分配(Node.FValue)然後',但如果我刪除這部分它將編譯和工作。我是否需要這個,或者如果省略,是否會導致更多的問題? – Shambhala

+0

如果您已填充數據結構和/或使用記錄,則不需要此行。基本上我習慣在使用VirtualStringTree時寫這個。 – Linas

+0

謝謝你解釋這部分,並再次爲你的幫助:) – Shambhala

1

看起來你需要實現OnSaveNode和OnLoadNode事件:

procedure TForm.VTLoadNode(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Stream: TStream); 
begin 
    // Load Node Data record from the stream 
end; 

procedure TForm.VTSaveNode(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Stream: TStream); 
begin 
    // Save Node Data record to the stream 
end;