Как я могу сохранить и загрузить свою структуру данных svTree?

Я пытаюсь реализовать простой менеджер контактов, используя компонент VirtualStringTree. Я настроил его так, чтобы он выглядел как компонент представления списка только с тремя столбцами, которые будут содержать текст:

раскладка

Для структуры данных я использую svTree от Linas, о котором упоминалось в другом вопросе переполнения стека.

Я объявил запись как это:

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'), но когда он загружен обратно, древовидное представление не содержит данных, только пустая строка.

2 ответа

Решение

Вам необходимо установить процедуры OnLoadNode и OnSaveNode для вашего TSVTree и реализовать свою логику здесь. Вы можете посмотреть Project2 в папке Demos. Например:

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. Конечно, вы можете использовать свой собственный способ для записи ваших данных в поток.

Похоже, вам нужно реализовать события 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;
Другие вопросы по тегам