是关于Treeview 读取节点的问题
有一存储节点信息的表
table:
typ_code(节点的代码)
typ_name(节点名称)
node (节点所属于的层数)例子:01
Delphi
10101
Delphi数据库编程
2Delphi为父节点,Delphi数据库编程为他的子节点
其后都符合这个规律,
0101001为Delphi数据库编程的子节点假如表中有无数个记录的话,我们怎么把他们从表中读取到Treeview中呢?
有一存储节点信息的表
table:
typ_code(节点的代码)
typ_name(节点名称)
node (节点所属于的层数)例子:01
Delphi
10101
Delphi数据库编程
2Delphi为父节点,Delphi数据库编程为他的子节点
其后都符合这个规律,
0101001为Delphi数据库编程的子节点假如表中有无数个记录的话,我们怎么把他们从表中读取到Treeview中呢?
同时如过该节点有父节点的话,保存父节点的AbsoluteIndex,
那你再由数据库读出的时候就很简单了.
procedure UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);//更新树
function GetNodeLevel(sFormat,sCode:string):integer; //获得节点层数
function GetNodeItem(sCode:string):integer;//获得item { Public declarations }
end; const
CTreeCodeFormat='122222';
cTreeMaxLevel=6;
CTreeRootTXT='所有图书';var
tsgzlfrom: Ttsgzlfrom;
_err:integer;
curUser:string[10];
mystate:string;
gNodeId:string;
gNodelevel:integer;
gNode:TtreeNode;
mynode:array[0..6] of TTreenode;
i,Already,CurMode:integer;
currow:integer;
iniFile:string;
HasSub:String; level:Integer;
implementationuses bgNewunit;
{$R *.DFM}procedure TtsgzlFrom.LoadTree(treeDB:TDBDataSet);//初始化树
var curID,nodeTxt:string;
level,num:integer;
begin
//初始化变量
Screen.Cursor:=crHourGlass;
tree.Enabled:=True;
tree.Items.Clear;
level:=1 ;
num:=1;
tree.items.clear;
//设置根节点
mynode[level]:=Tree.items.add(Tree.Topitem,cTreeRootTxt);
mynode[level].ImageIndex:=0;
mynode[level].SelectedIndex:=1;
//遍历数据表,利用编码字段记录排序规律,依次添加树节点
with TreeDb do
begin
try
if not Active then open;
first;
while not Eof do
begin
curID:=trim(FieldByName('tsglb').AsString);
nodeTxt:=curID+'-'+trim(FieldByName('tsglbn').AsString);
level:=GetNodeLevel(cTreeCodeFormat,curID);
//这里返回代码的层次数
if level>0 then
begin
//增加下一节点时,用添加子节点的方法可轻松实现节点间的层次关系。
//注意:这里的父节点是用当前节点的上一级节点mynode[level-1]
mynode[level]:=Tree.Items.AddChild(Mynode[level-1],NodeTxt);
mynode[level].ImageIndex:=2;
mynode[level].SelectedIndex:=3;
end;
next;//下一条记录
end;
finally;
close;
End;
mynode[1].expand(False);
Screen.Cursor:=crHourGlass;
end;
end;function TtsgzlFrom.GetNodeLevel(sFormat,sCode:string):integer;
var i,iLen:integer;
begin
level:=-1 ;
iLen:=0;
if (sFormat<>'') and (sCode<>'') then
for i:=1 to Length(sFormat) do //分析编码格式,找出当前代码层次
begin
iLen:=iLen+StrToInt(sFormat[i]);
if Length(sCode)=iLen then
begin
level:=i;
break;
end;
end;
result:=level;
end;Function TtsgzlFrom.GetNodeItem(sCode:string):integer;//获得item
var i,iCount,val:integer;
tmp:string;
begin
Result:=0;
iCount:=Tree.Items.Count;
if iCount=0 then exit;
val:=0;
for i:=1 to iCount-1 do
begin
Tmp:=Tree.Items.Item[i].Text;
Tmp:=Copy(Tmp,0,pos('-',Tmp)-1);
if Tmp=sCode then begin
val:=i;
Break;
end;
end;
result:=val;
end;procedure TtsgzlFrom.UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);
Begin
if state='add' then
begin
curNode:=Tree.Items.addchild(curNode,nodeTxt);
curNode.ImageIndex:=2;
curnode.SelectedIndex:=3;
end;
if state='del' then curNode.delete;
if state='edi' then curNode.Text:=nodeTxt;
end;
字段名 說明 類型 長度 是否可為Null 是否主鍵
Add_ID ID號 INT (自增型)
ItemNo 產品編碼 VC 50 N Y
Parent_No 上階編碼 VC 50 N Y
Code_No 料品編碼 VC 50 N Y當然ItemNo也可不要,但需要時在某些操作上會方便很多及對數據管理也有好處.
當ItemNo = Parent_No = Code_No 說明這是最終的產品
Parent_No指向Code_No的父料號項.
以下是我用的一個遍歷算法,僅供參考: //在這裡Edit1.Text為產品編碼Procedure TFrmBOM.RefreshTreeNode; //從後台數據庫中提取數據生成所有結點
var TreeNode:TTreeNode;
begin
TreeView1.Items.Clear;
TreeNode:=TreeView1.Items.Add (nil,Edit1.Text);
TreeNode.ImageIndex:=1;
TreeNode.Selected:=True;
GetTreeNode(TreeNode); //畫結點
end;Procedure TFrmBOM.GetTreeNode(Parent_Node:TTreeNode;IsGetChild:Boolean=False); //得到料號下的結點(父項料號)
var TreeNode:TTreeNode;
begin
IF not IsGetChild then
begin
with Query5 do
begin
Close;
SQL.Clear;
SQL.Add('Select Code_No From Bom where ItemNo='+''''+Edit1.Text+''''+
' and Parent_No='+''''+Parent_Node.Text+''''+' order by Code_No');
Open;
end;
IF Query5.RecordCount>0 then
begin
Query5.First;
while not Query5.Eof do
begin
if Query5.Fields[0].asstring<>Parent_Node.Text then
begin
TreeNode:=TreeView1.Items.AddChild(Parent_Node,Query5.Fields[0].asstring);
TreeNode.ImageIndex:=1;
TreeNode.SelectedIndex:=3;
TreeNode.Selected:=true;
end;
Query5.Next;
end;
IF Parent_Node.GetFirstChild<>nil then
begin
GetTreeNode(Parent_Node.GetFirstChild);
end
else
IF Parent_Node.getNextSibling<>nil then
GetTreeNode(Parent_Node.GetNextSibLing)
else
IF Parent_Node.Parent<>nil then GetTreeNode(Parent_Node.Parent,true)
else Exit;
end
else
begin
IF Parent_Node.GetNextSibling<>nil then
GetTreeNode(Parent_Node.GetNextSibLing)
else
IF Parent_Node.Parent<>nil then GetTreeNode(Parent_Node.Parent,True)
else Exit;
end;
end;
IF IsGetChild then
begin
IF Parent_Node.GetNextSibling<>nil then
GetTreeNode(Parent_Node.GetNextSibling)
else
IF Parent_Node.Parent<>nil then GetTreeNode(Parent_Node.Parent,True)
else Exit;
end;
end;
-----------------------Delphi
Delphi 数据库编程
...
其它
...如果是可以用两张表 :
ID Name
1 Delphi
2 其它
------------
Ids Names
1 Delphi数据库编程
1 Delphi网络编程
1 ...
2 其它编程
===================================================
var
Tn : TTreeNode ;
Tn1 : TTreeNode ;
TnArr : Array of TTreeNode ;
i , j : Integer ; Tn := TreeView1.Items.Add(Nil,'库') ;
Tn1 := TreeView1.Items.AddChild(tn,'dddd') ;
i := 0 ;
j := 1 ;
With ADOQuery1 do
begin
Close ;
Sql.Text := 'select Distinct ID from table1 ' ;
Open ;
SetLength(TnArr,RecordCount) ;
While Not Eof do
begin
TnArr[i] := TreeView1.Items.AddChild(tn,FieldByName('ID').AsString) ;
Next ;
Inc(i) ;
end;
for i := 0 to RecordCount-1 do
begin
With ADOQuery1 do
begin
Close ;
Sql.Text := 'select Names from Table2 where IDs = '''
+ TnArr[i].Text + '''' ;
try
Open ;
except
end ;
While Not Eof do
begin
Try
TreeView1.Items.AddChild(TnArr[i],FieldByName('Names').AsString) ;
Next ;
Except
End ;
end ;
end ;
end ;
end ;
strings.SaveToStream(stream);
treeview.LoadFromStream(stream);OK
但是不知道怎么处理
如果把TREEVIEW中的内容存如TXT
那格式是这样的01
0101
010101
0102
010201
02
0201
0202
.
.
.
.
.
.wjlsmail(计算机质子) 你那个不怎么好啦.
太局限了嘛~
第一层代码直接写,然后每下一层在前面添加一个空格就可以了。