之前在寫CSS有關文章的時候,我就想寫寫如何使用ASP.NET控件能夠更加CSS Friendly,更容易實現一些常見的頁面布局pattern,然而之後就發現這並非那麼容易的。說起來要讓ASP.NET控件變得CSS Friendly很容易,直接使用ASP.NET 2.0 CSS Friendly Control Adapters就是了,然而事實並非如此簡單。
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以及全新的TemplateControl形式
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屬性,從而讓你能在整個網站中保持命名風格一致性。
Web Form的屈服?
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細節的控件。