之前在写CSS有关文章的时候,我就想写写如何使用ASP.NET控件能够更加CSS Friendly,更容易实现一些常见的页面布局pattern,然而之后就发现这并非那么容易的。说起来要让ASP.NET控简变得CSS Friendly很容易,直接使用ASP.NET 2.0 CSS Friendly Control Adapters就是了,然而事实并非如此简单。
首先请允许我对这个CSS Friendly Control Adapters抱怨一下。我第一眼看到它输出的class名称我就觉得很faint了,举一些例子:AspNet-Menu、AspNet-Menu-WithChildren、AspNet-Menu-Leaf。如果你习惯了客户端代码一律使用camel命名法的话,你看到这样的命名就会觉得无法适从,你是要改变原有的命名法来迁就这些控件呢,还是让多种命名法在你的CSS文件中混排呢。如果需要改变这些默认的class命名呢?不好意思,控件自身的CssClass属性已经没有任何作用,因为控件输出的HTML结构都改变了,那些CssClass也就不再对应哪个HTML元素了。因此,如果你需要改变这些class命名,唯一的办法就是直接更改ControlAdapter的源代码,而class命名是以字符串形式硬编码在源代码中的,就算你用搜索替换你还是会害怕替换多了或者替换少了从而引入了更多的麻烦。
说到源代码,这些ControlAdapter的第二个麻烦也就浮现了——网站必须携带它们的所有源代码,而不仅仅是编译好的dll,而且这些源代码的可修改性并不强。为什么说可修改性不强?如果你有想过自己写一些ControlAdapter的哈,我想你已经参考过现有的那几个ControlAdapter了,你会发现编写ControlAdapter严重依赖于你对该Control本身的理解,不仅仅是对Control公开部分的了解,还需要对Control内在逻辑的深入理解。因此,要么你是Control的作者本身,要么你就细看过Control的源代码,否则不可能写出ControlAdapter,甚至修改已有的都很难。
因此,CSS Friendly Control Adapters是一个非常之鸡肋的选择,我们不如向前看,看看Microsoft在ASP.NET 3.5中为我们提供了什么。
ListView是ASP.NET 3.5新引入的一个控件,如果你还没有使用上Orcas,或者没试用过这个控件,那么不妨看看ScottGu的介绍性文章:The asp:ListView control。这篇文章详细说明了如何先设计一个原型页,然后设计LINQ to SQL以便获取数据,在将数据绑定到ListView上面,最后还加上DataPager分页。我们不需要看那么多,看ListView那部分就是了,看看声明ListView的代码。
如果你熟悉之前Atlas提供的Sys.UI.Data.ListView,那么你一定会觉得这两个ListView很相似。与之前的TemplateControl(例如GridView)不同,ListView不再直接输出容器本身的代码,而提供了一个Template给你自定义容器,你可以在这个Template中自由编写你的容器代码,它可以是<table />,也可以是<ul />或<ol />。之后项目的Template也是允许自定义的,对应<table />的自然是<tr />,而对应<ul />与<ol />的则应该是<li />。因为这些都是你手动编写的HTML代码,所以你可以随意地给它们设置class属性,从而让你能在整个网站中保持命名风格一致性。
ASP进化到ASP.NET的时候,好像Win Form那样的拖放控件支持成为了最大的特色,然而现在Web Form的编写方式又变回和其它服务器端脚本语言(例如VBScript)差不多了。以前ASP的时候,不就是自己写容器的HTML咯,然后用<%For ... Next%>把项目HTML圈起来,现在改为叫做模板其实没什么差别啊,况且其他服务器端脚本语言都有类似的写法,不过可能是helper函数或者别的称呼,都差不多。
因此,事实证明除非放弃对HTML细节的控制权(而这又难以做到CSS Friendly),否则对于大多数服务器端语言来说声明数据表现模板的方式都是类似的,没有更便捷的方式了。能够省事的是数据访问方法,从ADO进化到ADO.NET,从Typed DataSet到LINQ to SQL。将来Microsoft是否会发布更多类似的TemplateControl还很难说,因为ListView已经有非常高的可定制性,原来用来表示二维表数据结构的DataControl都可以用它作为替代品,同领域的控件已经没意义了,不像以前要分开几个DataControl了。我觉得接下来最好能看到一个取代Menu的CSS Friendly Control,因为Menu所表现的数据结构不是二维表,而是树,有必要为这种数据结构提供一个能准确声明HTML细节的控件。
最后,如果你对我的blog中关于ASP.NET与CSS的文章感兴趣的话,可以考虑订阅: