delphidata-structuresvirtualtreeviewtvirtualstringtree

How can I save and load my svTree data structure?


I am trying to implement a simple contact manager using the VirtualStringTree component. I have it set up to look like a list-view component with only three columns that will all contain text:

Layout

For the data structure, I am using svTree by Linas, which was mentioned in another Stack Overflow question.

I have declared a record like this:

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

In the form's OnCreate I have this:

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

I am adding the data from TEdits like this:

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;

How can I save this into a stream or a file to be loaded back? I have tried using MyTree.SaveToFile('C:/Test.dat') and MyTree.LoadFromFile('C:/Test.dat'), but when it's loaded back the tree view contains no data, only a blank row.


Solution

  • You need to set OnLoadNode and OnSaveNode procedures for your TSVTree and implement your logic here. You can look at Project2 in the Demos folder. E.g.:

    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;
    

    After that you can just call MyTree.SaveToFile('C:/Test.dat') or MyTree.LoadFromFile('C:/Test.dat'). In my demo and this example i've used another unit (uSvHelpers) which implements TStream helper for more OO stream support. You can of course use your own way to write your data information to stream.