Как я могу сохранить и загрузить свою структуру данных svTree? - PullRequest
3 голосов
/ 12 сентября 2011

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

Layout

Для структуры данных я использую 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 ]

3 голосов
/ 12 сентября 2011

Вам необходимо установить процедуры OnLoadNode и OnSaveNode для вашего TSVTree и реализовать свою логику здесь. Вы можете посмотреть Project2 в папке Demos. 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;

После этого вы можете просто позвонить MyTree.SaveToFile('C:/Test.dat') или MyTree.LoadFromFile('C:/Test.dat'). В моей демонстрации и в этом примере я использовал другой модуль (uSvHelpers), который реализует хелпер TStream для большей поддержки потоков OO. Конечно, вы можете использовать свой собственный способ для записи ваших данных в поток.

1 голос
/ 12 сентября 2011

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