今天比较郁闷的一件事情,就是用TreeView动态加载目录,从数据库中将目录读出来。
- b" y# ?( I. a! n6 ?这个应该用动态规划比较简单,但是最近确实是用脑过度了,脑子里全是浆糊,就用下面要讲的死办法了~~==!
2 m N/ P1 {( _4 f, w因为数据库设计的时候没有考虑到动态目录树的问题,没有在数据表中比较有前瞻性地设置上级编号、下级编号,只能将不同级别的目录内同一个一个找出来,我的这次,就用到了三张表,采用3重循环将数据添加到TreeNode中去:- step1:绑定节点数据
9 _1 o* R* y Y9 H8 e2 M! Y - public TreeNode GetTreeNode()4 ` h, T* k1 X
- {//这个函数还要做优化,因为这样写和数据库的交互会比较多,待有时间了再修改好了
, ?5 l- a4 [1 i. Y - int i = 0;2 ?2 X3 a6 |6 ~) R) f
- int n = 0;; G! @) o3 [% H6 X, T+ Z
9 u# t4 y, @$ z- this.currentUserID = (int)Session[SessionStr.CurrentUserID];
: r5 k" _5 p0 o/ Z - 4 m2 h& C! j5 j& |+ r; Y% r9 b6 r" n( i
- TreeNode treeNode = new TreeNode();& p0 x) L2 Z8 V; X2 Z
- DataTable dtCourse = CourseManagementBL.GetCourseIDListByStudentUserID(this.currentUserID);
4 ~4 @0 @+ g% \ A) d: X - foreach (DataRow row in dtCourse.Rows)
4 b+ ?* F# d1 u - {
8 d& M4 G) R4 A - treeNode.ChildNodes.Add(new TreeNode(row[1].ToString()));
) {% @8 ^$ e" K - foreach (DataRow Experiment_row in ExperimentManagementBL.GetExperimentNameListByCourseID(int.Parse(row["courseID"].ToString())).Rows)
1 i' l$ X* W; J4 ?7 o - {' ~; p! v4 o4 o* ^
- TreeNode expNode = new TreeNode();
! D8 ]4 G+ q$ r% l s6 H - expNode.Text = Experiment_row[1].ToString();
8 b5 B, |5 f6 j; _2 u* t8 |9 ^ - treeNode.ChildNodes[i].ChildNodes.Add(expNode);
+ s/ t& I% z0 Q, T8 M
0 U2 `' S& F' P5 u, f! p3 n P- //treeNode.ChildNodes[i].ChildNodes.Add(new TreeNode(Experiment_row[1].ToString()));! r( K6 y, j" T+ I* Z6 J; i
- foreach (DataRow Practice_row in PracticeManagementBL.GetPracticeIDListByExperimentID(int.Parse(Experiment_row["experimentID"].ToString())).Rows)
* V0 H, m# i% u1 G, U0 m - {! m0 p0 o* e8 s4 c/ N' C
- treeNode.ChildNodes[i].ChildNodes[n].ChildNodes.Add(new TreeNode(Practice_row[1].ToString()));
5 O4 J0 h* w. S: T) { - }8 n# K6 e1 ^, l
- n++;) d6 v3 z3 y) p8 b3 i1 ]; L
- }
9 G9 N M. ^ h+ ? - i++;# `7 R, Z# I' F. ?
-
4 H0 y( Y: |' m+ \) ^: ?: T3 a% H - }
; N& {# |2 P0 ^7 X$ r' j. t" R. H - return treeNode;
- n$ \. X4 h% I B& F4 x' D - }
- ^& k' Z" T' T& r C: _1 }
复制代码 step2:将节点内容添加到TreeView中# P. Y& X7 ?* E5 N" }! r1 Y8 ~
也就是在这一步发现了TreeView中一个比较奇怪的东西,每将treeNode中一个节点Add到treeView中时,会自动地将treeNode的被添加的这个节点删掉(为什么为什么为什么???),这样就不能用foreach了,因为foreach只能读只读的数据
. y; x. ], y4 f. w |2 @: k
, f7 P+ e9 ^8 {& g/ ?/ t! E那就直接Add整个treeNode吧(asp.net这个倒是挺自动化的),代码简单:
8 q0 q7 P7 _: \& NTreeNode tn = this.GetTreeNode();
# W4 f# e; t& ]3 |5 z: M9 ^this.tvCourseMenu.Nodes.Add(tn);
4 l( R& `! b" A3 y* M+ H* g问题也有,我用GetTreeNode函数返回的是一个TreeNode,是一个,所以生成的目录最上级是一个空的根目录(我在做数据绑定的时候没有绑定根目录的值啦,当然如果绑定了也可以没有下面的step3了),我想去掉这个,肯定不能Remove啦,因为Remove根目录,整个的都没啦。4 D$ ^% J; s- s
step3:
1 W, R4 R; w& A# L: e2 H用循环绑定根目录的子目录" ?0 I' ^0 g5 O0 p# R" {' i7 q: h
【不能这样】7 Y$ h2 J6 V: o d
for (int i = 0; i < tn.ChildNodes.Count;)
0 y! T( k! E2 {, t0 m {, F! p" B# X e& A0 R
this.tvCourseMenu.Nodes.Add(tn.ChildNodes);
1 P# `- \$ E7 V2 U" c) p. S }& v" e# g+ K: e$ w
【只能这样】; I& \0 E9 ?4 I! ~( P! i* X. g
while (tn.ChildNodes.Count != 0)
S6 C1 P9 _& ` {- T. W: E% R1 |7 g* a9 o- y
this.tvCourseMenu.Nodes.Add(tn.ChildNodes[0]);5 a4 U& |' q/ \! i* i9 [
}
3 c/ x" b% i! [9 |, a/ g【理由】上面说了已经! y6 t9 l) q0 D$ x% r
( l3 J: a; c0 q7 Z* E$ Z2 b @, N6 ~
终于弄好了,在做这个遇到step2中的问题的时候去请教了一个实验室的师兄,结果直接说,“我基本不用服务器控件的”,巨囧啊~~看来微软的这种控件还是有一些优化空间的啊,难怪不断地有VS05、08、10 |