今天比较郁闷的一件事情,就是用TreeView动态加载目录,从数据库中将目录读出来。- r9 ?* d, R8 ` ?8 `
这个应该用动态规划比较简单,但是最近确实是用脑过度了,脑子里全是浆糊,就用下面要讲的死办法了~~==!) a. \; B8 R# Y2 q
因为数据库设计的时候没有考虑到动态目录树的问题,没有在数据表中比较有前瞻性地设置上级编号、下级编号,只能将不同级别的目录内同一个一个找出来,我的这次,就用到了三张表,采用3重循环将数据添加到TreeNode中去:- step1:绑定节点数据
3 y3 [! `' |6 N0 s+ L - public TreeNode GetTreeNode()
4 l2 S# J# P I% R+ E2 f6 z# R - {//这个函数还要做优化,因为这样写和数据库的交互会比较多,待有时间了再修改好了% q4 o1 F' `4 y- X( ?* O
- int i = 0;3 ?9 R+ t4 K# [2 i3 Y6 n. @
- int n = 0;3 U! i3 p) A" |( @9 w
- ^0 k6 \) {# o! U- this.currentUserID = (int)Session[SessionStr.CurrentUserID];! u+ y- b! d- c" T/ V" P: s8 \
- 8 a1 w. x& D* o G3 y3 v
- TreeNode treeNode = new TreeNode();
! [9 x+ X! e @; d; V6 j. B - DataTable dtCourse = CourseManagementBL.GetCourseIDListByStudentUserID(this.currentUserID);$ y3 `- I2 e2 a1 B1 i
- foreach (DataRow row in dtCourse.Rows)9 q( Z! R+ e6 O; e
- {
$ x" S- j3 K# t" g3 H6 d* h5 X - treeNode.ChildNodes.Add(new TreeNode(row[1].ToString()));' V5 b; p) A/ ~6 }- J5 U* n9 U# r
- foreach (DataRow Experiment_row in ExperimentManagementBL.GetExperimentNameListByCourseID(int.Parse(row["courseID"].ToString())).Rows)
5 e& n' t/ J. L; ] - {% x8 i, y& }" z% B
- TreeNode expNode = new TreeNode();
. C. W) T$ J( C3 ~1 ?# G" Y" v - expNode.Text = Experiment_row[1].ToString();8 x0 a" e4 H5 M6 A3 v5 F( h5 |
- treeNode.ChildNodes[i].ChildNodes.Add(expNode);
* {4 J. o' h5 Z4 \/ m - 8 q- _2 @7 l- ]9 w; x5 ]
- //treeNode.ChildNodes[i].ChildNodes.Add(new TreeNode(Experiment_row[1].ToString()));
3 O8 S) F! C3 P - foreach (DataRow Practice_row in PracticeManagementBL.GetPracticeIDListByExperimentID(int.Parse(Experiment_row["experimentID"].ToString())).Rows)/ U- e' o* S8 o
- {
S! _# V, D- c; {0 S5 D, K - treeNode.ChildNodes[i].ChildNodes[n].ChildNodes.Add(new TreeNode(Practice_row[1].ToString()));
- R. \2 A6 ?; h/ M1 K - }8 S. e! C0 q) w2 x" o- I/ e* u
- n++;6 p: ]3 |3 K! p+ h5 A8 f
- }$ X, } x8 O/ y* x
- i++;
/ m- M- W' P; | - 0 O* s5 K+ t7 b3 l2 `3 d4 M
- }& G; n' F4 G) [6 ?0 `/ e4 P K1 o
- return treeNode;
0 o, L' B+ G$ C3 h# D - }
7 V# Z/ I! M6 g8 ~0 @' a+ r6 q
复制代码 step2:将节点内容添加到TreeView中5 Y2 v, y u4 `5 u+ E, G$ B9 h9 Z8 ?
也就是在这一步发现了TreeView中一个比较奇怪的东西,每将treeNode中一个节点Add到treeView中时,会自动地将treeNode的被添加的这个节点删掉(为什么为什么为什么???),这样就不能用foreach了,因为foreach只能读只读的数据# T. d5 V3 v* R w/ p: T3 x
$ q: e" A! B: ]( J+ y4 m那就直接Add整个treeNode吧(asp.net这个倒是挺自动化的),代码简单:
- x7 D+ w' Y+ k# i5 Y2 FTreeNode tn = this.GetTreeNode(); ?5 c" ]5 c, i( o8 a9 J
this.tvCourseMenu.Nodes.Add(tn);
( Y+ o/ H9 \2 |# Z0 I7 J. [1 l! w问题也有,我用GetTreeNode函数返回的是一个TreeNode,是一个,所以生成的目录最上级是一个空的根目录(我在做数据绑定的时候没有绑定根目录的值啦,当然如果绑定了也可以没有下面的step3了),我想去掉这个,肯定不能Remove啦,因为Remove根目录,整个的都没啦。1 c; ~& C$ |1 U
step3:# V3 Q8 y! K& t! _5 t
用循环绑定根目录的子目录
1 A( S+ e9 f. v! M3 e【不能这样】
+ D% u. |6 s, M; }! S8 @3 lfor (int i = 0; i < tn.ChildNodes.Count;)1 N3 m- T- U* ~6 H- P: c) T9 _* j% ?
{) h4 l- t3 [( @
this.tvCourseMenu.Nodes.Add(tn.ChildNodes);
) z+ M( `+ c$ Y# W# N }
; g. a! @( Q6 |$ }8 y8 k2 [1 w! O8 ]4 W【只能这样】
5 D o; u9 T/ N- a: ~while (tn.ChildNodes.Count != 0)
+ E& a) P- n* u; B. Z {
" e, a6 w/ W1 x# s% n this.tvCourseMenu.Nodes.Add(tn.ChildNodes[0]);7 k. A/ O- U9 ]) l
}' y$ Q1 B+ C7 H! C. Q! }. t }
【理由】上面说了已经
7 ?! @( B$ ?+ X# c! _6 l, A/ A' {
终于弄好了,在做这个遇到step2中的问题的时候去请教了一个实验室的师兄,结果直接说,“我基本不用服务器控件的”,巨囧啊~~看来微软的这种控件还是有一些优化空间的啊,难怪不断地有VS05、08、10 |