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

timelyraining 2002-05-29 07:09:04
请问各位搞人,如何用treeview实现数据库的分层显示,数据量很大
...全文
72 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;
打开链接下载源码: https://pan.quark.cn/s/d85aa9a28238 FreeRTOS,其全称为“Free Real-Time Operating System”,是一款具备开源特质且设计轻巧的实时操作系统(RTOS),主要应用于嵌入式系统领域。该“freertos工程文件以及官方文档.rar”压缩包内含了与FreeRTOS关联的工程文件、官方文档资料以及其他用于移植的文件,是进行FreeRTOS学习与应用的关键性资源。 FreeRTOS的核心特质涵盖任务调度机制、中断处理功能、同步机制设计以及内存管理策略。其中,任务调度机制是其核心功能,借助优先级抢占式调度算法,保障高优先级任务能够获得及时响应。中断处理功能是嵌入式系统中的关键环节,FreeRTOS支持在中断执行环境中开展特定操作,同时确保任务执行状态的安全。同步机制例如信号量、互斥量及事件标志组,主要用于实现任务之间的通信与协调。内存管理部分则负责动态分配和释放内存资源,以满足不同任务的特定需求。 工程文件通常由源代码、配置文件、编译脚本等构成,能够帮助开发者深入理解FreeRTOS的工作原理,并在此基础上进行定制化开发。例如,`FreeRTOSConfig.h`作为FreeRTOS的核心配置文件,允许用户依据目标硬件条件和应用需求调整内核参数,比如任务数量、堆大小等。 官方文档资料是学习FreeRTOS的重要参考资料,其内容详尽地阐述了系统架构、API函数、应用示例等关键信息。通过研读这些文档,开发者可以掌握如何创建任务、配置中断、实现任务间的同步与通信,以及如何对FreeRTOS系统进行调试和优化。 移植文件主要涉及将FreeRTOS部署于不同的微控制器(MCU)或硬件平台之上。每个平...

5,944

社区成员

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

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