2007. július 31., kedd
Save and load a TTreeView to / from a stream
Problem/Question/Abstract:
I'd like to use the TreeView component for hierarchizing some data. For this, I need to add to every node an integer property which will refer to the primary key field of an associated database. Alas, I fear that the TreeView "SaveToFile" and "LoadFromFile" methods save/ load only the Text property! Then, how can I save and load this integer property (and by the way, the imageindex) for every node?
Answer:
By writing your own save and load routines. Untested! Don't forget to rewind the stream before loading when you test this code.
procedure SaveTreeviewToStream(tv: TTreeview; S: TStream);
var
writer: TWriter;
node: TTreeNode;
begin
Assert(Assigned(tv));
Assert(Assigned(S));
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);
writer.WriteInteger(Integer(node.data));
node := node.GetNext;
end;
writer.WriteListEnd;
writer.FlushBuffer;
finally
writer.Free;
end;
end;
procedure LoadTreeviewFromStream(tv: TTreeview; S: TStream);
var
reader: TReader;
node: TTreeNode;
level: Integer;
begin
Assert(Assigned(tv));
Assert(Assigned(S));
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;
end;
node.Text := Reader.ReadString;
node.ImageIndex := Reader.ReadInteger;
node.Data := Pointer(Reader.ReadInteger);
end;
reader.ReadListEnd;
finally
reader.Free;
end;
finally
tv.items.Endupdate;
end;
end;
I'd rather suggest to use the data pointer as a pointer to a real object, not as integer (in the SaveTreeviewToStream procedure). You could add more complex info inside this object, like type information, or even the data objects itself. Type information is essential if your treeview browses through different tables of your database.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése