2011-09-12 32 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;