TreeView上的节点连同其关联的对象的保存

字体大小: 中小 标准 ->行高大小: 标准
保存对象要稍难一些,因为在TreeNode中只存了个指针,除非TreeNode.Data是一个能用流操作的对象。如果是这样:(简单示范)

var

s1: TFileStream;

s2: TMemoryStream;

nCount, i: Inteter;

 

procedure CopyStream( sSrc, sDest: TStream );

begin

nCount := sSrc.Size;

sDest.Write( nCount, sizeof(nCount) ); // 请写入字节数

sDest.CopyFrom( sSrc, 0 ); // 写入TreeView的内容,第二个参数为0表示全部复制

sSrc.Size := 0; // 清掉以前数据

end;

 

begin

s2 := TMemoryStream.Create;

// 保存到文件

s1 := TFileStream.Create( '文件名', fmCreate );

TreeView.SaveToStream( s2 );

CopyStream( s2, s1 );

// 下面写入TreeNode的Data

for i:=0 to TreeView.Items.Count-1 do

begin

if Assigned(TreeView.Items[i].Data) then

begin

s2.Write( i, sizeof(i) ); // 保存序号,如果你有更好标识方法,可以代替

TYourDataClass(TreeView.Items[i].Data).SaveToStream( s2 ); // TYourDataClass只是假定的名字

CopyStream( s2, s1 );

end;

end;

 

s1.Free; // 在Free之前它会保存的

 

// 从文件读取

s1 := TFileStream.Create( '文件名', fmOpenRead );

s1.ReadBuffer( nCount, sizeof(nCount) );

s2.CopyFrom( s1, nCount );

TreeView.LoadFromStream( s2 );

// 下面读入TreeNode的Data

while s1.Position<s1.Size do

begin

s1.ReadBuffer( i, sizeof(i) );

s1.ReadBuffer( nCount, sizeof(nCount) );

s2.CopyFrom( s1, nCount );

TreeView.Items[i].Data := TYourDataClass.Create; // 当然,可能Create调用格式是另外的

TYourDataClass(TreeView.Items[i].Data).LoadFromStream( s2 );

end;

s1.Free;

 

s2.Free;

 

这个例子不一定能满足你的要求,不过至少你可以参考一下。因为在你的程序里,可能TreeView.Items[i].Data还有别的变量指着。但你可以变化一下。比如倒着赋值。

******************

我曾经这样来记录我的TREEVIEW,不知道和你的想法是否一致:

{伪代码}

{假设表中有一个TREEVIEW,这里定义一个结构做为节点关联的DATA}

type PitemData=^TItemData;

TItemData=record

caption:string;

data:integer;

end;

----------------------------------------

建树的过程:

循环:

新建一个PITEMDATA的指针,

为指针的域赋值,

新建一个节点,

节点的DATA=新指针,

保存文件的过程:

创建一个新文件:

得到当前树节点的最顶层节点数,向文件中写节点数,开始循环节点数,遍历每个节点

然后向文件中分别写入是否有子节点,有多少个子节点,每个节点下指针的数据.根据层次的增加可能会使用递归(类似于读目录树一样)将所有数据写入文件.

------------------------------------

导入文件的过程:

打开相应文件,

依照上面保存的方法得到树结构节点数,然后使用导入数的过程,为它们分配指针,填充适当的数据.

记住:在程序退出时,要记得释放为每一个节点分配的指针.其实这个做法和TREEVIEW的SAVETOFILE差不多,但是是以二进制保存,而且相当于使用一个自己定义结构的数据表.

这个虽然不是依照上面意思所做的工作,但是有些类似.

他简单在层次固定,数据格式固定,但是如果要修改,照上面的结构也很容易,如果你愿意告诉我你想记录你的什么样的树图,我可以写源码给你.

//这一段是把文件读出,形成树

procedure TForm1.Button3Click(Sender: TObject);

Var

F:Integer;

i,j:integer;

CurrentNode:TTreeNode;

ChildNode:TTreeNode;

ChildCount:integer;

Nowx,Nowy:integer;

begin

TreeView1.Items.Clear ;

F:=FileOpen('main.RGN',fmOpenRead);

if F<0 then exit;

FileRead(F,RegionCount,sizeof(integer));

for i:=1 to RegionCount do begin

FileRead(F,childcount,sizeof(integer));

//这一段是记录树的数据.

procedure TForm1.Button2Click(Sender: TObject);

Var

F:Integer;

i,j:integer;

CurrentNode:TTreeNode;

ChildNode:TTreeNode;

ChildCount:integer;

begin

F:=FileCreate('main.RGN');

if F<0 then exit;

Filewrite(F,RegionCount,sizeof(integer));

CurrentNode:=TreeView1.Items.GetFirstNode;

for i:=1 to RegionCount do begin

Childcount:=currentNode.Count ;

Filewrite(F,ChildCount,sizeof(integer));

FileWrite(F,PPoint(CurrentNode.data)^.x,sizeof(integer));

FileWrite(F,PPoint(CurrentNode.data)^.y,sizeof(integer));

ChildNode:=CurrentNode.getFirstChild ;

for j:=0 to CurrentNode.Count-1 do begin

fileWrite(F,PPoint(ChildNode.data)^.x,sizeof(integer));

FileWrite(F,PPoint(ChildNode.data)^.y,sizeof(integer));

ChildNode:=childNode.getNextSibling;

end;

CurrentNode:=CurrentNode.getNextSibling ;

end;

FileClose(F);

end;

Fileread(F,Nowx,sizeof(integer));

FileRead(F,Nowy,sizeof(integer));

CurrentNode:=TreeView1.Items.Add(nil,format('x:%d,y:%d',[Nowx,nowy]));

for j:=0 to ChildCount-1 do begin

Fileread(F,Nowx,sizeof(integer));

FileRead(F,Nowy,sizeof(integer));

childNode:=TreeView1.items.Addchild(CurrentNode,format('x:%d,y:%d',[Nowx,nowy]));

end;

end;

FileClose(F);

end;

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/68046.html