我想用TREEVIEW 中的DATA属性来保存部门编号如123456,不知该怎么做,还请多帮忙,,,,一定结帖的。。。。。。。
我也看过用STATEINDEX实现的但感觉效果不太好,,
用tag保存好了 如果是数字的话
建议用一个数组来对应treeview,用absluteindex作为数组的索引,想记什么就放数组里 很方便
保存对象要稍难一些,因为在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;
type Prec=^Trec //声明指针
Trec=record
bmmc:string;//可以为任意类型
bmrs:integer;
end;
procedure Tform1.button1click(sender:Tobject);
var
p:prec;
begin
p.bmmc:=aaaaa;
p.bmrs:=6;
treeview1.addobject(null,sdfsdf,p);
或treeview1.addchildobject(node,ssss,p);
end;
试试
这篇文章请参考
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Db, ADODB;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
Button1: TButton;
ADOQuery1: TADOQuery; //连接department
ADOQuery2: TADOQuery; //连接worker
Edit1: TEdit; //结点信息
procedure Button1Click(Sender: TObject);//生成树
procedure TreeView1Click(Sender: TObject);//显示结点信息
procedure FormClose(Sender: TObject; var Action: TCloseAction);//释放p_data
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
p_data:pstring;
implementation
{$R *.DFM}
//生成树
procedure TForm1.Button1Click(Sender: TObject);
var
fn,sn:ttreenode; //fn:部门结点 sn:员工结点
begin
treeview1.Items.BeginUpdate;
adoquery1.close;
adoquery1.sql.clear;
adoquery1.sql.add(select * from department);
adoquery1.open;
treeview1.Items.Clear;
new(p_data);
p_data^:=root;
fn:=treeview1.Items.AddObject(nil,root,p_data);
while not adoquery1.Eof do
begin
with treeview1.Items do
begin
new(p_data);
p_data^:=adoquery1.fieldbyname(d_no).asstring;
sn:=treeview1.Items.AddChildobject(fn,adoquery1.fieldbyname(name).asstring,p_data);
adoquery2.close;
adoquery2.sql.Clear;
adoquery2.sql.add(select * from worker where d_no=:d_no);
adoquery2.Parameters.ParamByName(d_no).value:=p_data^;
adoquery2.open;
while not adoquery2.Eof do
begin
new(p_data);
p_data^:=adoquery2.fieldbyname(w_no).asstring;
treeview1.Items.addchildobject(sn,adoquery2.fieldbyname(name).asstring,p_data);
adoquery2.Next;
end;
end;
adoquery1.Next;
end;
adoquery1.Close;
adoquery2.close;
treeview1.Items.EndUpdate;
end;
//显示结点信息
procedure TForm1.TreeView1Click(Sender: TObject);
begin
if treeview1.Selected=nil then exit;
case treeview1.Selected.Level of
1:begin
edit1.text:=部门号:+pstring(treeview1.selected.Data)^;
end;
2:begin
edit1.text:=工号:+pstring(treeview1.selected.Data)^;
end;
end;
end;
//释放p_data
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if p_data<> nil then Dispose(p_data);
end;