只剩下5分而以,但还是要试一下。请教一个关于TreeView的问题。(5分)

O

okzjq

Unregistered / Unconfirmed
GUEST, unregistred user!
有四张表,系院 XY(XYH,XYM),专业 ZY(ZYH,ZYM),班级 BJ(BJH,BJM)
学生简况 XS(XH,XM,BJH)。
现在窗体左边放TREEVIEW,右边放DBGRID,TreeView显示大概如下:
信息学院
计算机专业
99计算机一班
99计算机二班
电子专业
99电子一班
99电子二班
当在TreeView中双击一个班时,右边显示一个班的学生,当专业一个专业时,显示
该专业的学生。


现我只有分,等我积够分数,我会为你加上的。现请你指点下!
 
嗯,想法不错,你想问什么?[:D]
 
怎么把表里面的东西添加到treeView里面啊,请帮忙啊!!!
还有,在TreeView中双击一个班时,右边显示一个班的学生,当专业一个专业时,显示
该专业的学生。
帮忙!!!!

附上我写的关于在treeView里面添加班级的代码,但执行速度很慢。如下:
procedure TForm1.Button1Click(Sender: TObject);
var
xsh,zyh:string;
xsNode,zyNode:TTreeNode;
begin
TreeView1.Items.Clear;
ADOQuery1.First;

while not ADOQuery1.Eof do
begin
xsh:=trim(ADOQuery1.FieldByName('XSH').AsString);
xsNode:=TreeView1.Items.Add(nil,ADOQuery1.FieldByName('XSM').AsString);


//添加该系的专业
ADOQuery2.Close;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('select * from BZY where XSH='''+xsh+'''');
ADOQuery2.Open;
ADOQuery2.First;
while not ADOQuery2.Eof do
begin
zyh:=trim(ADOQuery2.FieldByName('ZYH').AsString);
zyNode:=TreeView1.Items.AddChild(xsNode,ADOQuery2.FieldByName('ZYM').AsString);

//添加该专业的班级
ADOQuery3.Close;
ADOQuery3.SQL.Clear;
ADOQuery3.SQL.Add('select * from BBJ where ZYH='''+zyh+'''');
ADOQuery3.open;
ADOQuery3.First;
while not ADOQuery3.Eof do
begin
TreeView1.Items.AddChild(zyNode,ADOQuery3.FieldByName('BJ').AsString);
ADOQuery3.Next;
end;
// End 添加该专业的班级

ADOQuery2.Next;
end;

ADOQuery1.Next;
end;

end;


 
1stClass!?


good luck!
 
如果你确认你的专业名和班级名不会相同,就可以!
我正在做教育信息化的软件!
我已经做了和你需要的相同的效果!
 
你的做法基本可行,不过这样查询不方便。解决办法是利用好每个节点的Object属性
Object中利用动态内存分配存储节点编号,当双击节点时利用编号查询数据库即可。
我有一段代码如下:
type
PInfoId = ^TInfoId;
TInfoId = Record
Id: string;
end;
IdInfo: TInfoId;
//加的时候。
New(IdInfo);
IdInfo^.Id := MDetailQy['MInfoId'];
LevelThreeNode := MTypeTView.Items.AddChildObject(LevelTwoNode,
MDetailQy['MInfoName'] + '(' +
MDetailQy['Model'] + ')',
IdInfo);
//取的时候。
PInfoId(MTypeTView.Selected.Data)^.Id


 
你最好改改数据库,这样一个循环就可以了,我曾经设计过一个无限级的TREEVIEW,
并且可以多级拖动/ 蒋切/复制,关键是数据库,每个接点在数据库都有该接点的路径,当然
如果你不支持拖动就不用这样了,
 
to:康凌,专业表里没有重复的专业名!你已经实现了该效果,能不能说说你实现的办法,
能说详细点嘛?
to:cyf_00002, 如果我改动数据库 ,是不是把系,专业,班 三个表合成一个表,
如单位(单位号,单位名,所属单位)?

但上面的做法毕竟TREEVIEW里的节点数据要从数据库取出,运行时较慢!
我有个想法是:没置一个合局变量FLAG ,当TREEVIEW从数据库取出数据后,设置
FLAG 为TURE,并把所有TREENODE 保存到文件里, 下次打开窗体时,如果FLAF 为TRUE,
则直接从文件导入,如果FLAG 为FAILE 则再从数据库取数据。而 系,专业,班三个表当
有数据改动时就把FLAG没为FAISE。

上面仅是我的想法,你觉得怎样呢? 你的想法呢? 能说一下嘛?

 
我的想法是:
1只做4次循环,每次循环做一次查询,第一次填系对象,第二次填专业,第三次填班级,
第四次填学生。每次查询时和上一级关联的字段必须和上一次的排序方式一样,这样你只
要检查是不是有变化就可以了(不考虑没有下一级的情况,如果考虑只要判断一下前边的
条件是否一样就可以了)

2节点可以用内存流生成后再显示或以流的形式输出到文件。如果可以按照系保存到单独
文件,可能会在下次加载时速度有所提高,弊端是会造成每次修改数据都要重新导出文件。

3我也比较赞同展开时才添加节点,设第一次加载100个系(有那么多吗),单击一个系最
多也就30个专业吧,每个系算50个班,每个班50-120人,每次单击一次查询,速度应该是
可以接受的,同时避免了数据修改后的刷新问题。
 
无论你们怎么处理都要考虑好专业名与班级名重复的情况,这样的话就不能用名称做
查询条件。如果这样做了以后系统的可扩展性就几乎没有了,这样设计从理论上也不允许。
这样的话只能利用编号做索引,就必需利用好节点的Object属性。
另外我坚决反对把三个表合成一个表,这样系统的扩展性同样不好。
系统启动时只生成学院与专业这两级,当访问专业的班级时再添加班的节点。添加时利用
专业的Object属性取出Id从数据库中取出此专业的班级即可。此方法如果利用好TreeView
的一些事件速度问题很好解决。
 
同意0000鬼0000的建议,我曾经用这种办法,使速度提高了不少
 
我是这样来填充TreeView的:
Procedure FillFieldToTreeView(AdoTable : TADOTable;FieldName : String;TreeView :TTreeView;ParentNode : TTreeNode ;bAll : Boolean);
var
bTemp1,bTemp2 : Boolean ;
Tmpstr : String ;
Begin
bTemp1 := AdoTable.Active ;
bTemp2 := AdoTable.Filtered ;
if not bTemp1 Then
AdoTable.Open ;
if bAll Then
begin
if bTemp2 Then
AdoTable.Filtered := False ;
end;
//
ParentNode.DeleteChildren ;
Adotable.First ;
While Not AdoTable.Eof Do
Begin
tmpstr := AdoTable.FieldByName(FieldName).AsString ;
TreeView.Items.AddChild(ParentNode,tmpstr);
AdoTable.Next ;
End;
//
AdoTable.Active := bTemp1 ;
AdoTable.Filtered := bTemp2 ;
End;
 
顶部