有谁能先解决,加分还提供源码 (100分)

  • 主题发起人 主题发起人 szlgx
  • 开始时间 开始时间
S

szlgx

Unregistered / Unconfirmed
GUEST, unregistred user!
这样写只想请大家尽快帮忙,因刚接触,还很菜,所以代码就更菜了,到时留下EMail,
看到后当然又要给我提建议啦!

想赶在放假前为我校用DELPHI6编制一个小的教师管理软件(以前用VF6)现在有一个
问题我参考了好多资料及别人贴的问题都一直未完成,希望各位高手帮忙解答:左边用
TreeView控件显示各教研组名称,右边PageControl及DBGrid、DBEdit等组件显示各项信息。
要求能在树中增加、删除、修改、拖动数据且数据表中的数据也作相应的变化。提出的方
案或解答尽可能详细,因我还什么都不懂。
XX学校
 |--初一语文组
 |  |--aa
| |--bb
|--初二语文组
 | |--cc
| |--dd
删除父结点时它下面的子结点数据全部删除,选择初一语文组时,在右边PageControl
的DBGrid中可显示初一语文组的全部教师,选择aa教师时,在右边PageControl的多个
DBEdit中可编辑、修改aa教师的各项数据。在树上拖动aa到初二语文组时,数据表中aa的信
息作相应的改动。(数据表要用VF6格式)。

 
如下资料:作为参考



TreeView在电信综合统计管理系统中的应用

陶占红 单 莹

--------------------------------------------------------------------------------


前 言
树形图用于显示按照树形结构进行组织的数据,其用途比较广泛,如计算机中的文件系统(Windows95中的资源管理器)、企业或公司的组成结构等。VB、PB、Delphi等工具提供了一个功能很强的树型控件TTreeView,可以用来描述复杂的层次关系。由于树形图结构较复杂,使用起来常不知如何下手。笔者结合电信综合统计管理系统中指标维护这一具体实例,详细阐述在Delphi下如何将树型控件的使用与数据库联系起来,实现数据分任意多层显示,方便地进行增加、修改、删除操作,而且用拖放技术实现各层数据之间的移动、复制。笔者希望通过对该实例的阐述,达到抛砖引玉的效果,与各位同仁相互交流,共同进步。
一、指标树的建立
具体方法是:创建一个数据库,设计指标表t_pub_index,包含index_id、parent_id、index_name字段,其它字段根据实际业务而定,指标名称index_name将在树型控件的节点上显示,index_id字段保存节点的唯一标识号,parent_id表示当前节点的父节点号,标识号组成了一个“链表”,记录了树上节点的结构。设计一窗体Frm_sys_index,其上放置TreeView控件tv_zb、Query控件Query1及其它指标属性编辑显示控件。一个树的节点又包含文本(Text)和数据(Data)。Text为String类,用来显示指标或指标目录名称。Data则为无定形指针(Untyped Pointer),可以指向一个与节点相联系的数据结构,该结构与数据库指标表相应域关联,如指标ID、上级节点ID。
Query控件的表达式为:
select index_id, parent_id, index_name from t_pub_index
start with index_id=0 connect by prior index_id=parent_id
其中start with 和connect by 是Oracle的SQL语句的保留字,使一条记录的parent_id列的值等于前一记录的index_id列的值,并以parent_id等于0的记录开始。
建树的基本思路是:
procedure TFrm_sys_index.createtree;
var
curValue: indexPointer; //指向与节点相联系的数据结构的指针
curNode : TTreeNode; //当前节点
curid : integer; //当前节点标识号
begin
curNode := nil;
curid := -1;
Query_index.Open;
Query_index.first;
while not Query_index.Eof do
begin
new(curValue);
With curValue^ do
将数据库指标表t_pub_index各字段值赋curValue 所指数据结构
while(curid <> curValue.parent_id) do //当前节点的标识号不等于当前记录的父节点号
begin
curNode := curNode.parent;
curid:= indexPointer(curNode.data).index_id;
end;
curNode := tv_zb.Items.AddChildObject(curNode,
curValue^.index_name,curValue); //在当前节点上添加子节点,显示节点指标名称,所带指针指向一个与指标数据相联系的数据结构
curid := indexPointer(curNode.data).index_id;
Query_index.next;
end;
Query_index.close;
end;
二、增加、删除、修改树节点
单纯在Treeview 上增加、删除、修改节点只需用它本身提供的Treeview.Items. AddChildObject、 Treeview.Selected.Delete、Treeview.Selected.EditText等方法即可,但要相应修改数据库中的数据,必须通过递归调用同一个函数(用于删除一个选项)来遍历所选节点下的所有子节点。下面以删除节点为例介绍具体实现流程:
function TFrm_sys_index.delnode(node1:TTreenode):TTreenode;
var
childnode:TTreenode;
begin
childnode:=node1.GetLastChild; //按倒序获得子项,因为删除选项时,列表会发生变化
while childnode<>nil do
childnode:=delnode(childnode); //如子项不为空,进行递归调用
index_id:=inttostr(indexpointer(node1.data).index_id);//获得该节点对应指标
在数据库删除相应指标;
result:=node1.parent.GetPrevChild(node1); //定位到该节点的上一节点
node1.delete; //删除树节点
end;
三、拖动树节点
拖动树节点基本上是通过建立目标项的新子项、向它复制源项、删除原项来移动选项。与上述删除操作相似,也是通过递归调用同一个函数(用于移动一个选项),按倒序移动所选节点下的所有子节点。下面是递归过程的代码:
procedure TFrm_sys_index.CopyNodeUnder(treeview:TTreeview;
sourcenode,targetnode:ttreenode);
var
newnode:ttreenode;
i:integer;
begin
newnode:=treeview.items.addchildfirst(targetnode,''); //建立目标项
newnode.assign(sourcenode); //复制源项属性
for i:=sourcenode.count-1 downto 0 do //递归调用,按倒序移动其所有子项
CopyNodeUnder (treeview,sourcenode.item,newnode);
treeview.items.delete(sourcenode); //删除源项
end;
Treeview对拖动操作提供支持,我们将组件的DragKind属性设置为dkDrag,DragMode属性设置为dmAutomatic,并为OnDragOver与OnDragDrop事件编写了处理程序。OnDragOver事件处理程序对允许移动的条件进行判断,排除需要避免的特殊情况。代码如下:
procedure TFrm_sys_index.tv_zbDragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
var
targetnode,sourcenode:TTreenode;
begin
targetnode:=tv_zb.getnodeat(x,y);
if (Source=Sender) and (targetnode<>nil) then //保证移动在TreeView上,且目标节点不为空
begin
Accept:=true;
sourcenode:=tv_zb.selected;
//以下代码防止用户将一个选项拖到其子项上(它会随着选项一起移动,导致死循环)
while (targetnode.parent<>nil) and (targetnode <> sourcenode) do
targetnode:=targetnode.parent;
if (targetnode = sourcenode) then Accept:=false;
end
else Accept:=false;
end;
OnDragDrop事件处理程序启动前述移动过程CopyNodeUnder,修改数据库数据。此外,在大批量添加数据到Treeview中时最好使用TreeView.Items.BeginUpdate和  TreeView.Items.EndUpdate,这样能加快显示速度。大致流程如下:
procedure TFrm_sys_index.tv_zbDragDrop(Sender, Source: TObject; X,
Y: Integer);
var
targetnode,sourcenode:TTreenode;
begin
targetnode:=tv_zb.getnodeat(x,y); //获得源节点
sourcenode:=tv_zb.selected; //获得目标节点
修改数据库中当前节点的父节点号parent_id,使其等目标节点标识号;
tv_zb.items.beginupdate; //禁用TreeView重绘操作
try
copynodeunder(tv_zb,sourcenode,targetnode); //启动移动过程
tv_zb.selected:=targetnode;
finally
tv_zb.items.endupdate; //重新设置
end;
end;
四、结束语
以上阐述数据库的树状显示的基本方法,以及如何在对树节点进行维护(增加、删除、修改、拖动)的同时,修改数据库数据。由于篇幅所限,笔者在此只对基本思路和流程作了介绍,并未列出详细源代码,读者可自行完善。本文程序在Dlphi5.0、Oracle8.0、Windows 98下调试通过。

(网页编辑:徐向阳)


相关文章
在Delphi中轻松实现自动排序
在 Delphi中定制提示窗口
Outlook的Automation对象编程方法
用Delphi开发视频捕获程序
用Delphi5.X编写调用动态链接库的应用程序

您的姓名: 您朋友的E-mail:
[关闭窗口]

--------------------------------------------------------------------------------



Copyright(C) ccw.com.cn,All rights reserved

中国计算机世界出版服务公司版权所有
 
to cbdiy:
  请你再讲详细点,我刚接触,实在懂的不多。
 
可以先定义一个探出式菜单,设置treeview右键为弹出式菜单,这样在菜单象里定义各种操作
如:删除、更改、插入、增加等操作。
 
   我正在学习这个内容,请高手们赐教,借点风。
 
真的没有人帮我和szlgx了吗?高手们、好人们都不在吗?
 
直接用DbTreeview就行了,数据库里的数据变化了,DbTreeview会自动改变,
你所要做的就是操作数据库
我这有一个for d5的,要的话留下email

另:有问题可以发信到qing_h@21cn.com
 
可以一起讨论我刚刚学了一点
jiancn@163.net
 
to lanjiancn:
先谢你了,知道的和不知道的都能帮我,请发过来。EMAIL:SZ-LGX@163.COM。
若有什么问题,我把代码发过来你帮忙改一下。可以吗?
 
干脆跟你全作了算了!
 
这样的问题又不是很难,看看书和帮助就可以了。何必要贴代码,贴着烦,看着也难。
 
建议多找找书
 
to taozhiyu:

  很感谢你,作完后,咱们可好好交流一下!
 
到http://delphi.mychangshu.com
程云做了一个treeview demo可以看看。
 
你想编写这样子的程序的话!
一定要掌握好!TTREEVIEW这个控件中的一些重要特性!
比如说:selectedindex,add,level,imageindex等等!
再接和数据库来做!
当然还要用到一些方法!(上面所说的递归调用!(删除,添加等))
这样子的话就可以了!
 
我正在写一个电子商务配送系统,遇到同样问题!谢谢高手!
DELWIN443@SOHU.COM
 
to suns:
解决问题后,不要忘记告诉我一声。
Email:sz-lgx@163.com
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
923
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
848
DelphiTeacher的专栏
D
后退
顶部