我想用TTreeView与数据库连接,在TTreeView里将数据库表显示为树形结构。
我从网上找到一个很不错的例子,例子的主要代码如下(因忘了记下下载地址,该网站又无法上传附件,所以只贴上主要代码)。form上主要控件有TreeView1、ADOQuery1、ImageList1等,ImageList1里已经加上4个.ico图标,其他各个控件都设置好了。数据库表的结构主要是:
id号 国家名称 城市名称 公司名称
1 美国 城市1 公司1
2 美国 城市1 公司2
3 美国 城市1 公司3
4 美国 城市2 公司1
5 美国 城市2 公司2
6 英国 城市1 公司1
7 英国 城市1 公司2通过下面代码执行后在TTreeViews上显示如下的树结构:
美国
城市1
公司1
公司2
公司3
城市2
公司1
公司2
英国
城市1
公司1
公司2
............例程的原代码能在上面树结构的每个级别节点名称之前显示不同的图标,但是,拷到我的程序后,各级别节点名称之前只显示ImageList1的第0号图标,不知道为什么?主要代码如下:procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
Datasource1.enabled := Node.data <> nil;
if DataSource1.enabled then Table1.gotobook(node.data);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
FieldList := TStringList.create;
TreeView1.items.BeginUpdate;
ADOQuery1.first;
while not ADOQuery1.eof do
begin
TreeAddItem(TreeView1, GetFieldList, ADOQuery1.getBook, false);
ADOQuery1.next;
end;
FieldList.clear;
TreeView1.Alphasort;
TreeView1.items.Endupdate;
TreeView1.items[2].selected := true;
end;function TForm1.GetFieldList: TStringList;
begin
FieldList.clear;
FieldLis.add(ADOQuery1.fieldbyname('Country').asstring);
FieldList.add(ADOQuery1.fieldbyname('city').asstring);
FieldList.add(ADOQuery1.fieldbyname('Company').asstring);
Result := FieldList;
end;function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
var
ThisNode, Node: TTreeNode;
I: Integer;
begin
Node := nil; //nil = level 0 has no parent node
//this is checked by TreeFindItem
for I := 0 to Itemlist.count -1 do
begin
ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
if ThisNode <> nil then Node := ThisNode else
begin
if I < Itemlist.count -1 then
begin
if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
else Node := Sender.items.AddChild(Node, Itemlist[i]);
end else
begin
if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
end;
Node.stateIndex := Node.level + 1;
if Resort and (Node.parent <> nil) then Node.parent.alphasort;
end;
end;
Result := Node;
end;function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
begin
if NodeItem = nil then NodeItem := Sender.items.getfirstnode
else NodeItem := NodeItem.getfirstchild;
if (NodeItem <> nil) and (NodeItem.text <> Name) then
repeat
NodeItem := NodeItem.getnextsibling;
until (NodeItem = nil) or (NodeItem.text = Name);
Result := NodeItem;
end;
我从网上找到一个很不错的例子,例子的主要代码如下(因忘了记下下载地址,该网站又无法上传附件,所以只贴上主要代码)。form上主要控件有TreeView1、ADOQuery1、ImageList1等,ImageList1里已经加上4个.ico图标,其他各个控件都设置好了。数据库表的结构主要是:
id号 国家名称 城市名称 公司名称
1 美国 城市1 公司1
2 美国 城市1 公司2
3 美国 城市1 公司3
4 美国 城市2 公司1
5 美国 城市2 公司2
6 英国 城市1 公司1
7 英国 城市1 公司2通过下面代码执行后在TTreeViews上显示如下的树结构:
美国
城市1
公司1
公司2
公司3
城市2
公司1
公司2
英国
城市1
公司1
公司2
............例程的原代码能在上面树结构的每个级别节点名称之前显示不同的图标,但是,拷到我的程序后,各级别节点名称之前只显示ImageList1的第0号图标,不知道为什么?主要代码如下:procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
Datasource1.enabled := Node.data <> nil;
if DataSource1.enabled then Table1.gotobook(node.data);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
FieldList := TStringList.create;
TreeView1.items.BeginUpdate;
ADOQuery1.first;
while not ADOQuery1.eof do
begin
TreeAddItem(TreeView1, GetFieldList, ADOQuery1.getBook, false);
ADOQuery1.next;
end;
FieldList.clear;
TreeView1.Alphasort;
TreeView1.items.Endupdate;
TreeView1.items[2].selected := true;
end;function TForm1.GetFieldList: TStringList;
begin
FieldList.clear;
FieldLis.add(ADOQuery1.fieldbyname('Country').asstring);
FieldList.add(ADOQuery1.fieldbyname('city').asstring);
FieldList.add(ADOQuery1.fieldbyname('Company').asstring);
Result := FieldList;
end;function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
var
ThisNode, Node: TTreeNode;
I: Integer;
begin
Node := nil; //nil = level 0 has no parent node
//this is checked by TreeFindItem
for I := 0 to Itemlist.count -1 do
begin
ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
if ThisNode <> nil then Node := ThisNode else
begin
if I < Itemlist.count -1 then
begin
if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
else Node := Sender.items.AddChild(Node, Itemlist[i]);
end else
begin
if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
end;
Node.stateIndex := Node.level + 1;
if Resort and (Node.parent <> nil) then Node.parent.alphasort;
end;
end;
Result := Node;
end;function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
begin
if NodeItem = nil then NodeItem := Sender.items.getfirstnode
else NodeItem := NodeItem.getfirstchild;
if (NodeItem <> nil) and (NodeItem.text <> Name) then
repeat
NodeItem := NodeItem.getnextsibling;
until (NodeItem = nil) or (NodeItem.text = Name);
Result := NodeItem;
end;
解决方案 »
- 用api创建一个窗体(背景)......再加个100分的贴.....大师级别的帮帮我吧..请在8点前帮我完成,即可结贴.
- 一个上传QQ聊天记录的软件
- 请教一个简单问题,在线等待!
- 求助:在delphi盒子下载的FastReport.v2.5注册版现在不能用了,不知道为什么,谁能帮帮我
- 高分求教:如何得到一个DLL里的函数的声明。
- 如何在一个应用程序中调用另一个应用程序??
- 简单问题,突然想不起来怎么做了
- 在程序中如何调用AC'97声卡的升降调功能?
- 如何用NMSMTP控件发送HTML格式的电子邮件?
- 我的难题不断:如何将QuickReport结果页面保存为BMP格式文件?
- 急求一個實列:delphi如何調用Web Service???
- [有图]求助:客户端(client)隐藏服务端IP或端口的应用(至少netstat -an 下看不出)
美国
城市1
公司1
公司2
公司3
城市2
公司1
公司2
英国
城市1
公司1
公司2
............
http://www.jpcode.com/code/740/742/25844.htm
是Ttreenode的image/statindex确定的
设置Ttreenode的image/statindex和相对应的Timagelist中的index
数据库表的结构主要是:
id号 国家名称 城市名称 公司名称
1 美国 城市1 公司1
2 美国 城市1 公司2
3 美国 城市1 公司3
4 美国 城市2 公司1
5 美国 城市2 公司2
6 英国 城市1 公司1
7 英国 城市1 公司2将上面的表用TTreeView表示出来,而且,要在国家名称上面再加一个顶层,每一层用不同的图表
{
AnsiString id,textname;
TBook bmk;
ADODS->Filter="Address_Father="+Fid;
// Edit1->Text=;
//ShowMessage(ADODS->RecordCount);
while (!ADODS->Eof)
{ id = ADODS->FieldByName("Address_ID")->AsString;
textname=ADODS->FieldByName("Address_Name")->AsString;
node = Tree_User->Items->AddChild(node,textname);
node->ImageIndex=2;
bmk = ADODS->GetBook() ;
CreateSubTree(id,node);
node =node->Parent;
ADODS->Filter="Address_Father="+Fid;
if (ADODS->BookValid(bmk))
{
ADODS->GotoBook(bmk);
ADODS->FreeBook(bmk);
}
ADODS->Next();
}
return (true);
}
这是个CB的程序你把它改为一个过程吧
ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
if ThisNode <> nil then Node := ThisNode else
begin
if I < Itemlist.count -1 then
begin
if I = 0 then
begin
Node := Sender.items.Add(Node, Itemlist[i]);
Node .ImageIndex := 1;
end
else
begin
Node := Sender.items.AddChild(Node, Itemlist[i]);
Node .ImageIndex := 2;
end; end else
begin
if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
end;
Node.stateIndex := Node.level + 1;
if Resort and (Node.parent <> nil) then Node.parent.alphasort;
end;
end;
begin
Node := nil; //nil = level 0 has no parent node
//this is checked by TreeFindItem
for I := 0 to Itemlist.count -1 do
begin
ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
if ThisNode <> nil then Node := ThisNode else
begin
if I < Itemlist.count -1 then
begin
if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
else Node := Sender.items.AddChild(Node, Itemlist[i]);
end else
begin
if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
end;
Node.stateIndex := Node.level + 1;
Node.ImageIndex:= Node.level ; if Resort and (Node.parent <> nil) then Node.parent.alphasort;
end;
end;
Result := Node;
end;
然后if Node.level=0 then//如果是根结点(国家节点)
begin
Node.ImageIndex:= iid ;//指定图标,iid的最大值不能超过ImageList1中的图标数。
inc(i);
end;另外就是要注意TreeView要与ImageList关联。
begin
Node.ImageIndex:= iid ;//指定图标,iid的最大值不能超过ImageList1中的图标数。
inc(iid);
end;
Nodea.ImageIndex := 6;
Nodea.SelectedIndex := 7;AreaName := FieldByName('AREANAME').AsString;
HouseName := FieldByName('HOUSENAME').AsString;
HouseNo := FieldByName('HOUSENO').AsString;
Nodeb := rztvMainFrm.Items.AddChild(Nodea, FieldByName('AREANAME').AsString);
Nodeb.ImageIndex := 8;
Nodec := rztvMainFrm.Items.AddChild(Nodeb, FieldByName('HOUSENAME').AsString);
Nodec.ImageIndex := 9;
Noded := rztvMainFrm.Items.AddChild(Nodec,FieldByName('HOUSENO').AsString);
Noded.ImageIndex := 10;对于分级,我的处理是在信息登记的时候根据小区+楼幢+房间号生成一个编号,在TreeView显示的时候,先根据这个编号index,再处理。