树是组织信息的强有力工具,软件开发人员手中一定要有一棵称手的“树”。这篇文章以VS2008为例讨论ASP.NET提供的树控件“TreeView”,看看它是否足够强大,能否满足商业应用。
1 首次使用遇到的问题
很简单的,我在页面(WebForm)中添加一个“TreeView”,然后在设计视图里添加了几个静态节点,出于美观的需要,我想把节点用线连接起来,微软果然厚道,通过“自定义行图标”直接设置“LineStyle”为“Solid”,搞定!下面是显示效果:
我和大家一样困惑,为什么实线会断开?然后我开始在网上寻找答案。虽然很多人写了很多关于“TreeView”的技术文章,但我没有找到关于这个问题的讨论。为什么我一开始就遇到的问题这些文章完全没有提及,真想忍不住问一句:“你们真用过TreeView吗?”。没办法,我只有开始了自己的艰难探索之路。花了大半天,终于找到真相。在“.aspx”文件的源视图的顶部,有这样一条语句:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
它是如此的平凡,我一直当它空气。删除这句,然后运行,下面是正常的显示效果:
我不明白微软为什么要自动生成这条语句。查了一些资料,有点乱,不能给大家一个说法。总之以后大家养成良好的习惯,每当添加一个新页面(WebForm),随即删除这条语句。
2 动态填充
关于树的一个关键技术是“动态填充”,即在展开节点的时候才创建当前节点的子节点并显示。例如,通过树来显示某家企业的组织机构和机构内的员工(上千条记录),如果采用一次性生成整棵树的方法,势必会产生大量的数据检索操作,累积的时间消耗是不能承受的。改变实现,先生成一级子节点,当用户展开某个节点时再生成当前节点的子节点。让我们看看“TreeView”在这种技术需求上的表现如何。
抽象的思维一下,动态填充的实现思路应该是:单击某个节点左侧的“+”号,页面回发,在服务器端某个“填充”事件被执行,当前节点的子节点被生成。开发中对应的设计过程是:将节点的“PopulateOnDemand”属性设置为True,然后在树的“TreeNodePopulate”事件中编写代码填充当前节点(即被展开节点)。
注意,PopulateOnDemand属性是TreeNode的属性,而不是TreeView的属性。它的意义在于:因为叶子节点不需要填充,所以我们可以去掉叶子节点的“动态填充”特性(即将叶子节点的PopulateOnDemand属性设为False),从而避免一些无谓的处理。以下面的数据源为例:
DeptID DeptName ParentDeptID
1 行政部 0
2 人力资源部 0
3 市场部 0
4 技术部 0
5 游戏开发组 4
6 ERP开发组 4
7 核心技术组 4
这是展开前的效果: