今天比较郁闷的一件事情,就是用TreeView动态加载目录,从数据库中将目录读出来。
+ V4 U. e) S- C这个应该用动态规划比较简单,但是最近确实是用脑过度了,脑子里全是浆糊,就用下面要讲的死办法了~~==!
: E" N7 T8 z9 ^9 p因为数据库设计的时候没有考虑到动态目录树的问题,没有在数据表中比较有前瞻性地设置上级编号、下级编号,只能将不同级别的目录内同一个一个找出来,我的这次,就用到了三张表,采用3重循环将数据添加到TreeNode中去:- step1:绑定节点数据
' |9 U S' |% X3 i3 p% F; E4 n2 A - public TreeNode GetTreeNode()
5 Z! ?. L# h3 \* i; ? - {//这个函数还要做优化,因为这样写和数据库的交互会比较多,待有时间了再修改好了
0 l# p6 p* V1 S- q! b - int i = 0;
, N- L: L7 y% h: _! G. I - int n = 0;$ C4 ?8 ]/ ~+ K7 X7 {1 V0 H9 P
- 0 S7 I+ }7 X7 |% l$ M
- this.currentUserID = (int)Session[SessionStr.CurrentUserID];
6 h# m/ S; _- l/ |
5 F- X3 Y% V1 a' k$ d- TreeNode treeNode = new TreeNode();
V$ d$ s) h2 Y2 V5 d: n8 G# K - DataTable dtCourse = CourseManagementBL.GetCourseIDListByStudentUserID(this.currentUserID);, f- r. C( M9 g3 H
- foreach (DataRow row in dtCourse.Rows)7 u6 c3 O7 z' O0 l9 s# v* q% c
- {
- ^( |( x. C8 f. j0 c3 M8 J - treeNode.ChildNodes.Add(new TreeNode(row[1].ToString()));" _; ~/ v/ j. n1 U, _
- foreach (DataRow Experiment_row in ExperimentManagementBL.GetExperimentNameListByCourseID(int.Parse(row["courseID"].ToString())).Rows)
! c) d) `& a- M9 P Q. E+ y - {
: [) Y4 B* b" n - TreeNode expNode = new TreeNode();* B5 g' Y3 R h5 f* q+ ]# U8 S) q
- expNode.Text = Experiment_row[1].ToString();9 r* k+ d. s8 W( H! h: u# }
- treeNode.ChildNodes[i].ChildNodes.Add(expNode);. M7 Y! S7 r! U' c) H; h) d( g
1 g& M( }# O( n# X/ x$ u- //treeNode.ChildNodes[i].ChildNodes.Add(new TreeNode(Experiment_row[1].ToString()));
( a* Q$ }; `# c' E6 _5 {1 K - foreach (DataRow Practice_row in PracticeManagementBL.GetPracticeIDListByExperimentID(int.Parse(Experiment_row["experimentID"].ToString())).Rows)
( b8 B6 [" k- n - {0 G9 Z) K$ f7 f! @
- treeNode.ChildNodes[i].ChildNodes[n].ChildNodes.Add(new TreeNode(Practice_row[1].ToString()));3 N( m2 C( u/ _! C2 E- _4 r4 e* t
- }
2 \ D |1 _+ {6 N, E: i# T - n++;
. [' P5 w+ i2 u" H* V - }
) M6 L3 x% t' Q* w6 ` - i++;
) {2 Y0 v2 T$ ~2 ~/ ]3 A; l8 R X -
7 f" P" |* p7 n7 h* V Z5 S9 F7 W6 T - }: e7 L0 y1 ^7 @5 T- I) t
- return treeNode;
" _4 V% k* L& H& } - }
% w7 x1 r; k+ V+ w5 m0 S
复制代码 step2:将节点内容添加到TreeView中
" @" g2 `) }7 `3 `- x+ Q也就是在这一步发现了TreeView中一个比较奇怪的东西,每将treeNode中一个节点Add到treeView中时,会自动地将treeNode的被添加的这个节点删掉(为什么为什么为什么???),这样就不能用foreach了,因为foreach只能读只读的数据, x7 g# J" j+ ~1 o
3 D7 {+ A9 r) q6 _! C7 y那就直接Add整个treeNode吧(asp.net这个倒是挺自动化的),代码简单:
# f D2 f: J. ~TreeNode tn = this.GetTreeNode();0 ^3 X& U/ r; e* I3 e
this.tvCourseMenu.Nodes.Add(tn);
1 g# b6 @, A$ r0 [6 `问题也有,我用GetTreeNode函数返回的是一个TreeNode,是一个,所以生成的目录最上级是一个空的根目录(我在做数据绑定的时候没有绑定根目录的值啦,当然如果绑定了也可以没有下面的step3了),我想去掉这个,肯定不能Remove啦,因为Remove根目录,整个的都没啦。
@5 v5 q, E3 t! Nstep3:
+ \9 _# z! s( O5 S3 u- X# R用循环绑定根目录的子目录
# [: g, E# | j7 S: s/ l# R【不能这样】8 M7 x u u) z
for (int i = 0; i < tn.ChildNodes.Count;), ~3 ?! n( z. D* |" M7 H
{ H! ]+ D% I1 F1 B( r& X
this.tvCourseMenu.Nodes.Add(tn.ChildNodes);
% p8 D9 r+ I& U( O" v7 k }0 Q$ y6 C+ A* |& t
【只能这样】
4 u8 Y0 y* L ?6 ^0 {while (tn.ChildNodes.Count != 0)
, l, }4 H; T8 Y6 l9 { {
: T- c* Z8 a8 j: H this.tvCourseMenu.Nodes.Add(tn.ChildNodes[0]);
8 C% R. N u* F% g5 o- { }
e! }0 C" h' k+ d$ s; p) {8 t【理由】上面说了已经" N! ]8 y7 N6 P d- [3 v+ d7 |
4 X1 N9 o3 {! F$ G终于弄好了,在做这个遇到step2中的问题的时候去请教了一个实验室的师兄,结果直接说,“我基本不用服务器控件的”,巨囧啊~~看来微软的这种控件还是有一些优化空间的啊,难怪不断地有VS05、08、10 |