今天比较郁闷的一件事情,就是用TreeView动态加载目录,从数据库中将目录读出来。, l, v( C5 B% g. G
这个应该用动态规划比较简单,但是最近确实是用脑过度了,脑子里全是浆糊,就用下面要讲的死办法了~~==!) | m' g' @ C3 @9 {$ A7 m: t$ F
因为数据库设计的时候没有考虑到动态目录树的问题,没有在数据表中比较有前瞻性地设置上级编号、下级编号,只能将不同级别的目录内同一个一个找出来,我的这次,就用到了三张表,采用3重循环将数据添加到TreeNode中去:- step1:绑定节点数据
6 u$ b/ c1 A- M3 p; S8 d - public TreeNode GetTreeNode()
0 J/ _& |; e0 Q# d - {//这个函数还要做优化,因为这样写和数据库的交互会比较多,待有时间了再修改好了$ x/ t* ? `! _' ?7 f* Z" D
- int i = 0;
7 V, ]1 K; Z4 x0 J7 J - int n = 0;; Z; b* V \8 L4 A% O
+ g0 w) ?: M8 ~( A: }- this.currentUserID = (int)Session[SessionStr.CurrentUserID];5 y. j; A0 H" W, [
- , G. X+ R. T; d
- TreeNode treeNode = new TreeNode();
9 g9 Z0 I' ~3 Y2 W( X: z* | - DataTable dtCourse = CourseManagementBL.GetCourseIDListByStudentUserID(this.currentUserID);7 w) p0 O/ x. R+ t
- foreach (DataRow row in dtCourse.Rows)" j; s" H s" A4 Z" S4 j) G R/ k
- {
- Q- _" D3 C! l. u/ F f0 m0 O' v - treeNode.ChildNodes.Add(new TreeNode(row[1].ToString()));
; D5 u9 N$ [: W; @ l9 _8 d - foreach (DataRow Experiment_row in ExperimentManagementBL.GetExperimentNameListByCourseID(int.Parse(row["courseID"].ToString())).Rows)
' |1 p" ^: \/ a2 q5 X - {
0 x) @3 `, F0 e* U) `9 y2 X - TreeNode expNode = new TreeNode();
/ f9 P; k, v4 C. b" r - expNode.Text = Experiment_row[1].ToString();
d8 e: S5 F0 F+ i2 Y/ d0 x3 A. ] - treeNode.ChildNodes[i].ChildNodes.Add(expNode);
$ F& x7 p2 e8 ]8 ]+ K n - * c6 J" ~1 T0 |& d3 o
- //treeNode.ChildNodes[i].ChildNodes.Add(new TreeNode(Experiment_row[1].ToString()));
( I; i; X' l0 O1 T& G/ [& h - foreach (DataRow Practice_row in PracticeManagementBL.GetPracticeIDListByExperimentID(int.Parse(Experiment_row["experimentID"].ToString())).Rows)
) f/ V3 \4 f; t) g8 N: f+ B - {7 }' R0 W( R ^% U& c3 ^0 h+ h
- treeNode.ChildNodes[i].ChildNodes[n].ChildNodes.Add(new TreeNode(Practice_row[1].ToString()));
) v% C9 t, F4 x4 A/ V1 W - }
; [( ^* L" X9 ~6 n" g - n++;0 S8 n6 o4 T. r, H( g k' x9 `
- }9 A/ Z% `8 p: G4 u, N6 u: B' s
- i++;
: e9 E8 C! u; F- s6 z" I0 D - # D; Y9 k1 `4 n4 r- x
- }9 o, b6 [- U9 F
- return treeNode;3 _1 {0 N; Y, v, N; D
- }' }1 V, }1 y9 N( S, G$ V$ H
复制代码 step2:将节点内容添加到TreeView中1 V/ V' X) J$ w
也就是在这一步发现了TreeView中一个比较奇怪的东西,每将treeNode中一个节点Add到treeView中时,会自动地将treeNode的被添加的这个节点删掉(为什么为什么为什么???),这样就不能用foreach了,因为foreach只能读只读的数据
) W% l* d1 @' C2 e. M2 R+ O1 p5 ?4 Z& }$ z; E
那就直接Add整个treeNode吧(asp.net这个倒是挺自动化的),代码简单:2 S& o! V. k/ W
TreeNode tn = this.GetTreeNode();
7 g! \( R! Y# r7 q& Z. x/ l6 Uthis.tvCourseMenu.Nodes.Add(tn); 0 T* L2 i1 @' R3 F6 N9 U" ?4 H* M6 _
问题也有,我用GetTreeNode函数返回的是一个TreeNode,是一个,所以生成的目录最上级是一个空的根目录(我在做数据绑定的时候没有绑定根目录的值啦,当然如果绑定了也可以没有下面的step3了),我想去掉这个,肯定不能Remove啦,因为Remove根目录,整个的都没啦。- d' i! L' \: S5 T# I0 e V
step3:8 A2 H; _9 g' W7 F3 ^! R: y* O# }, L5 r
用循环绑定根目录的子目录
" e/ X7 T5 t0 R% B3 y5 \' d. D【不能这样】6 w+ z: J8 T0 P9 v
for (int i = 0; i < tn.ChildNodes.Count;)0 |1 C$ I6 A$ ]6 G
{
" Y6 L, M: r. H* f- m8 ^+ l5 S this.tvCourseMenu.Nodes.Add(tn.ChildNodes);
- B1 w5 [6 ^ G( p3 W }( l7 o# X3 B! D+ Q' h
【只能这样】- b6 S# l8 l. U. |
while (tn.ChildNodes.Count != 0)9 f1 h3 r$ ^ {
{' U, O8 V0 |* Y9 C
this.tvCourseMenu.Nodes.Add(tn.ChildNodes[0]);
/ O: J5 h! y7 z }- x; v# d& _9 T; W% M! H* x. u( N
【理由】上面说了已经7 u6 E; y5 M& h9 n
$ Q7 m4 X' l- c+ @2 D( j5 F, U终于弄好了,在做这个遇到step2中的问题的时候去请教了一个实验室的师兄,结果直接说,“我基本不用服务器控件的”,巨囧啊~~看来微软的这种控件还是有一些优化空间的啊,难怪不断地有VS05、08、10 |