![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Есть TreeView, к узлам привязаны данные.
Такая вот структура: Код:
type PNodeOptions = ^NodeOptions; NodeOptions=record Name: String[255]; Surname: String[255]; Address: String[255]; EMail: String[255]; end; Пожалуйста, помогите эти данные записывать и считывать из файла! Чтобы и дерево, и эти привязанные данные были в одном файле. Я обыскал все, ничего путного не нашел((( Очень нужна помощь! |
|
#2
|
|||
|
|||
|
Ну так и сериализуй.
Тут надо знать как узлы в дереве расположены (сколько корневых). Можно просто в xml сериализовать, тогда меньше мороки с корневыми узлами, но больше потом мороки с чтением всего этого добра обратно. |
|
#3
|
||||
|
||||
|
А что если радикально, пользуя сам компонет, через файловый поток
Код:
var
fs: TFileStream;
...
{Сохранить} fs:= TFileStream.Create('tv.sav', fmCreate or fmShareCompat);
{Загрузить} fs:= TFileStream.Create('tv.sav', fmOpenRead or fmShareDenyWrite);
try
{Сохранить} fs.WriteComponent(TreeView1);
{Загрузить} fs.ReadComponent(TreeView1);
finally
fs.Free;
end;
... |
|
#4
|
|||
|
|||
|
Цитата:
Не, если я правильно помню, то он привязанные данные не сохраняет, просто в силу того, что не знает как это делать. |
|
#5
|
|||
|
|||
|
Не работает, файловый поток сохраняет только само дерево, без данных!( еще варианты?
|
|
#6
|
||||
|
||||
|
Следуя вот этим рекомендациям вырисовывается лишь связка из сохранения структуры дерева в отдельном файле (см. код выше) и данных из нод, но так же в отдельном файле
Код:
...
type
PNodeOptions = ^TNodeOptions;
TNodeOptions = record
Name: string[255];
Surname: string[255];
Address: string[255];
EMail: string[255];
end;
procedure NodeSaveDataProc(Writer: TWriter; Data: Pointer);
begin
Writer.WriteListBegin;
with TNodeOptions(Data^) do
begin
Writer.WriteString(Name);
Writer.WriteString(Surname);
Writer.WriteString(Address);
Writer.WriteString(EMail);
end;
Writer.WriteListEnd;
end;
function NodeLoadDataProc(Reader: TReader): Pointer;
var
P: PNodeOptions;
begin
New(P);
try
Reader.ReadListBegin;
with P^ do
begin
Name:= Reader.ReadString;
Surname:= Reader.ReadString;
Address:= Reader.ReadString;
EMail:= Reader.ReadString;
end;
Reader.ReadListEnd;
except
Dispose(P);
raise;
end;
Result:= P;
end;
type
TNodeSaveDataProc = procedure(Writer: TWriter; data: Pointer);
TNodeLoadDataProc = function(Reader: TReader): Pointer;
procedure SaveTreeviewToStream(tv: TTreeview; S: TStream;
saveProc: TNodeSaveDataProc);
var
Writer: TWriter;
Node: TTreeNode;
begin
Assert(Assigned(tv));
Assert(Assigned(S));
Assert(Assigned(saveProc));
Writer:= TWriter.Create(S, 4096);
try
Node:= tv.Items[0];
Writer.WriteListBegin;
while Node <> nil do
begin
Writer.WriteInteger(Node.Level);
Writer.WriteString(Node.Text);
Writer.WriteInteger(Node.ImageIndex);
saveProc(Writer, Node.Data);
Node:= Node.GetNext;
end; { While }
Writer.WriteListEnd;
Writer.FlushBuffer;
finally
Writer.Free;
end;
end; { SaveTreeviewToStream }
procedure LoadTreeviewFromStream(tv: TTreeview; S: TStream;
loadProc: TNodeLoadDataProc);
var
Reader: TReader;
Node: TTreeNode;
Level: integer;
begin
Assert(Assigned(tv));
Assert(Assigned(S));
Assert(Assigned(loadProc));
tv.Items.BeginUpdate;
try
tv.Items.Clear;
Reader:= TReader.Create(S, 4096);
try
Node:= nil;
Reader.ReadListBegin;
while not Reader.EndOfList do begin
Level := Reader.ReadInteger;
if Node = nil then
// create root node, ignore its level
Node:= tv.Items.Add(nil, '')
else
begin
if Level = Node.Level then
Node:= tv.Items.Add(node, '')
else if Level > Node.Level then
Node:= tv.Items.AddChild(Node, '')
else begin
while Assigned(Node) and (Level < Node.Level) do
Node:= Node.Parent;
Node:= tv.Items.Add(node, '');
end; { Else }
end; { Else }
Node.Text:= Reader.ReadString;
Node.ImageIndex:= Reader.ReadInteger;
Node.Data:= loadProc(Reader);
end; { While }
Reader.ReadListEnd;
finally
Reader.Free;
end;
finally
tv.items.Endupdate;
end;
end; { LoadTreeviewFromStream }
procedure TForm1.Button1Click(Sender: TObject);
var
S: TFileStream;
begin
S := TFileStream.Create('Data.sav', fmCreate or fmShareCompat);
try
SaveTreeViewToStream(TreeView1, S, NodeSaveDataProc);
finally
S.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
S: TFileStream;
begin
S := TFileStream.Create('Data.sav', fmOpenRead);
try
LoadTreeViewFromStream(TreeView1, S, NodeLoadDataProc);
finally
S.Free;
end;
end; |
|
#7
|
|||
|
|||
|
Думаю, что смысла нет. Скорее всего, дерево обеспечивает только структуру (хотя я не знаю, какая информация "сидит" в заголовке самих нод, если просто объединение тех же данных, что и в прикрепленной записи, то смысла сохранения дерева нет вообще). В этом случае достаточно просто писать все ноды в отдельный файл (поток), а при чтении восстанавливать структуту по файлу.
ЗЫ. Писать код просто влом, там все достаточно просто. Сначала пишется кол-во корневых узлов, потом сами узлы и, рекурсивно, все их подузлы. При чтении - в обратном порядке. Вот псевдокод: Код:
procedure SaveTree(Stream : TStream);
var
I : Integer;
begin
WriteToStream(Stream,RootTreeCount);
For I := 0 To RootTreeCount-1 Do
SaveNode(Stream,Nodes[i]);
end;
procedure SaveNode(Stream : TStream; Node : TTreeNode);
var
I : Integer;
begin
WriteToStream(Stream,Node.Data);
WriteToStream(Stream,Node.Items.Count);
For I := 0 To Node.Items.Count-1 Do
SaveNode(Stream,Node.Items[i]);
end; |