|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Сохранение данных TreeView
Есть 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; |