特急,冒汗!!!有关treeview 的分层显示问题???

timelyraining 2002-05-29 07:09:04
请问各位搞人,如何用treeview实现数据库的分层显示,数据量很大
...全文
27 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ihihonline 2002-05-29
  • 打赏
  • 举报
回复
还没有结决?
ilang 2002-05-29
  • 打赏
  • 举报
回复
另外就是拖动节点的问题
tv.DragMode:=dmAutomatic

procedure TTreeV.tvStartDrag(Sender: TObject;
var DragObject: TDragObject);
begin
nodeText:=tv.Selected.Text;
end;

procedure TTreeV.tvEndDrag(Sender, Target: TObject; X, Y: Integer);
begin
Cursor:=crDefault;
try
tv.Selected.MoveTo(tv.GetNodeAt(X,Y),naInsert);
tv.GetNodeAt(X,Y).MoveTo(tv.Selected,naInsert);
except
showmessage('out of range');
end;
end;

procedure TTreeV.tvDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
Cursor:=crDrag;
end;

procedure TTreeV.tvDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept:=True;
end;
Billy_Chen28 2002-05-29
  • 打赏
  • 举报
回复
1、首先建立数据库:
ID NODENAME PARENT
2、使用ADO或其它方式存取数据库,并用SQL或其它方式选出记录
3、用用递归生成结点
ilang 2002-05-29
  • 打赏
  • 举报
回复
procedure TForm1.UpdateTree(curNode:TTreeNode;nodeTxt:string;state:string);
begin
if state='add' then
begin
curNode:=tree.Items.AddChild(curNode,nodeTxt);
curNode.ImageIndex:=2;
end;
if state='del' then curNode.Delete;
if state='edi' then curNode.Text:=nodeTxt;

end;

function TForm1.GetNodeLevel(sFormat,sCode:string):integer;
var
i,level,iLen:integer;
begin
level:=-1;
iLen:=0;
if (sFormat<>'') and (sCode<>'') then
begin
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;
end;

procedure TForm1.Table1NewRecord(DataSet: TDataSet);
begin
setFieldMask;
end;

procedure TForm1.Table1BeforeEdit(DataSet: TDataSet);
begin
setFieldMask;
end;

procedure TForm1.Table1AfterDelete(DataSet: TDataSet);
begin
UpdateTree(gNode,'','del');
end;

procedure TForm1.Table1AfterInsert(DataSet: TDataSet);
begin
mystate:='add';
end;

procedure TForm1.Table1AfterPost(DataSet: TDataSet);
var
nodetext:string;
begin
nodetext:=table1.fieldbyName('dwbm').Text+'-'+table1.fieldByName('dwmc').Text;
if mystate='add' then
UpdateTree(gNode,nodetext,mystate);
if mystate='edi' then
UpdateTree(gNode,nodetext,mystate);

mystate:='edi';
table1.Refresh;
end;

procedure TForm1.Table1AfterEdit(DataSet: TDataSet);
begin
mystate:='edi';
end;

procedure TForm1.Table1BeforeDelete(DataSet: TDataSet);
begin
if Application.MessageBox('确定要删除?','操作提示',
MB_OKCANCEL)<>IDOK then table1.cancel;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
table1.DatabaseName:='C:\My Documents\treeview';
LoadTree(table1);
end;

procedure TForm1.treeClick(Sender: TObject);
var
temp,recID:string;
n,m:integer;
curLevel:integer;

begin
gNode:=tree.Selected;
n:=Pos('-',gNode.text)-1;
recID:=copy(gNode.text,1,n);
gNodeID:=recID;
if gNode.text<>'单位字典' then
begin
if recID<>'' then
begin
with table1 do
begin
open;
active:=true;
FindNearest([recID]);
end;
curLevel:=getNodeLevel(cTreeCodeFormat,recID)+1;
end
else
curLevel:=1;
end;
gNodelevel:=curLevel;


end;

end.
ilang 2002-05-29
  • 打赏
  • 举报
回复
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, DB, DBTables, ImgList, ExtCtrls, DBCtrls, StdCtrls,
Mask, Grids, DBGrids;
const
cTreeCodeFormat='122222';//
cTreeMaxLevel=6;
cTreeRootTxt='单位字典';
type
TForm1 = class(TForm)
tree: TTreeView;
ImageList1: TImageList;
Table1: TTable;
Database1: TDatabase;
DBEdit1: TDBEdit;
DBEdit2: TDBEdit;
DataSource1: TDataSource;
DBNavigator1: TDBNavigator;
DBGrid1: TDBGrid;
procedure Table1NewRecord(DataSet: TDataSet);
procedure Table1BeforeEdit(DataSet: TDataSet);
procedure Table1AfterDelete(DataSet: TDataSet);
procedure Table1AfterInsert(DataSet: TDataSet);
procedure Table1AfterPost(DataSet: TDataSet);
procedure Table1AfterEdit(DataSet: TDataSet);
procedure Table1BeforeDelete(DataSet: TDataSet);
procedure FormCreate(Sender: TObject);
procedure treeClick(Sender: TObject);
private
{ Private declarations }
mystate,
gNodeID:string;
gNode:TTreeNode;
gNodelevel:integer;
procedure setFieldMask;

procedure LoadTree(treeDB:TDBDataSet);
procedure UpdateTree(curNode:TTreeNode;nodeTxt:string;state:string);
function GetNodeLevel(sFormat,sCode:string):integer;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.setFieldMask;
var
i,j:integer;
maskStr:string;
setField:TField;
begin
setField:=table1.FieldByName('dwbm');
if (gNodeID<>'') and (gNodelevel<cTreeMaxLevel) then
begin
maskStr:='';
if setField.DataSet.state=dsInsert then
j:=Length(gNodeID)
else
j:=Length(gNodeID)-2;
for i:=1 to j do
begin
maskStr:=maskStr+'\'+gNodeID[i];
end;
setField.EditMask:='!'+maskStr+'00;1;?';
end
else begin
setField.DataSet.Cancel;
end;
end;

procedure TForm1.LoadTree(treeDB:TDBDataSet);
var
curID,nodeTxt:string;
level,chindex,cnode,num:integer;
mynode:array[0..6]of TTreeNode;
begin
Screen.Cursor:=crHourGlass;
tree.Enabled:=True;
tree.Items.clear;
level:=0;
num:=1;
mynode[level]:=tree.Items.Add(Tree.TopItem,cTreeRootTxt);
mynode[level].ImageIndex:=1;
with treeDB do
begin
try
if not Active then open;
first;
while not EOF do
begin
curID:=trim(FieldByName('dwbm').AsString );
nodeTxt:=curID+'-'+trim(FieldByName('dwmc').AsString );
level:=GetNodeLevel(cTreeCodeFormat,curID);
if level>0 then
begin
mynode[level]:=tree.Items.addchild(mynode[level-1],nodeTxt);
mynode[level].ImageIndex:=2;

end;
next;
end;
finally
close;
end;
mynode[0].Expand(False);
Screen.Cursor:=crDefault;
end;
end;
ilang 2002-05-29
  • 打赏
  • 举报
回复
treeview的问题我上次也费了很长时间。因为数据量很大,所以合适的做法是在节点扩展的时候读取数据,即OnExpanding事件。在接点未扩展时,可以先赋予它一个临时数据,节点展开的同时把它删除。具体处理如下:
procedure TTree.FormCreate(Sender: TObject);
begin
tv.Items.Add(tv.TopItem,nodeTop).Selected:=True;
tv.Items.AddChild(tv.Selected,'temp');
end;

procedure TTreeV.tvExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
begin
tempNode:=Node.getFirstChild;
if (Node.Count>1) or (tempNode.Text<>'temp') then Exit;
with ADOQ do
begin
if Active then Close;
SQL.Clear;
SQL.Add('select * from Tree ');
Open;
First;
while not Eof do
begin
if trim(FieldByName('PNAME').AsString)=Copy (tempNode.Parent.Text,Pos('-',tempNode.Parent.Text)+1,Length (tempNode.Parent.Text)) then
begin
tempNode:=tv.Items.Add(tempNode,FieldByName('ID').AsString+'-'+FieldByName('Name').AsString);
tempNode.ImageIndex:=tempNode.Level;
tv.Items.AddChild(tempNode,'temp');
end;
Next;
end;
end;
if Node.getFirstChild.Text='temp' then Node.getFirstChild.Delete;
end;

如果涉及到多个数据表就更麻烦了,别人曾给我建议用数据流,具体我也没去试国,这边还有一个不错的别人的例子,你可以参考一下
superljj 2002-05-29
  • 打赏
  • 举报
回复
好象要用递归。
ihihonline 2002-05-29
  • 打赏
  • 举报
回复
如果数据量很在,就用treeview和数组;
或者,如上者;
Node,Node_1:TreeNode;
Node := TreeView.Items.add(Nil,String);//level := 0;
Node_1 := TreeView.Items.AddChild( Node_1 , String);//level := 1;
就这样类推
如:

//=================================
procedure Txsjbxxform.TreeViewCreate;
var
Node_1 , Node_2 : TTreeNode;
begin
with DataModuleForm.xsxxQuery2 do
begin
Close;
with SQL do
begin
Clear;
Add('select Distinct bjmc from xsjbxx ' ) ;
end;
Open;
First;
while Not (DataModuleForm.xsxxQuery2.Eof ) do
begin
Node_1 := TreeView1.Items.Add(Nil,FieldByName('bjmc').AsString );
Node_1.ImageIndex := 0;
Node_1.SelectedIndex := 1;
with DataModuleForm.xsxxQuery3 do
begin
Close;
with SQL do
begin
Clear;
Add('select * from xsjbxx where bjmc = :Value');
end;
Parameters.Items[0].Value := DataModuleForm.xsxxQuery2.FieldByName('bjmc').AsString ;
Open;
First;
while Not ( DataModuleForm.xsxxQuery3.Eof ) do
begin
Node_2 := TreeView1.Items.AddChild( Node_1 , FieldByName('xm').AsString + '-->' + FieldByName('bh').AsString);
Node_2.ImageIndex := 2;
Node_2.StateIndex := 3;
Node_2.SelectedIndex := 3;
Next;
end;
end;
Next;
end;
end;
qrlvls 2002-05-29
  • 打赏
  • 举报
回复
用递归搞定吧!
netlib 2002-05-29
  • 打赏
  • 举报
回复
MainTree.items.add(nil,'树根')
with MainTree do
begin
Ln:=Items.AddChild(Items[0].item[6],'K 蜡烛线');
LN.ImageIndex:=2; Ln.SelectedIndex:=2;
New(P); p.Value:=Integer(mtKLIne); P.ValueType:=IsMainMap;
Ln.Data:=P;
Ln:=Items.AddChild(Items[0].item[6],'Bar 美国线');
LN.ImageIndex:=2; Ln.SelectedIndex:=2;
Ln.Data:=P;
Ln:=Items.AddChild(Items[0].item[6],'TWR 宝塔线');
LN.ImageIndex:=2; Ln.SelectedIndex:=2;
Ln.Data:=P;
end;

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧