正是adapter让服务器端控件,变成了客户端的html标签。但是它到底又是怎么工作的呢?因为这个牵扯到“控件编程”的概念,而此概念似乎很难用两三句话简单的说明,所以这里不再详述。感兴趣的朋友可以在MSDN中关注下面的内容“HtmlContainerControl.Render”、“ HtmlTextWriter”、“ System.Web.UI.HtmlControls”……
虽然这里不会详细的讲解“控件编程”的知识,不过,大家可以放心,我们仍然会用一个实例来讲解怎么用adapter来实现将服务器端控件Label打到前台为Label标签而不是原来的span标签。
在讲实例之前我们要先讲一下VS2005中的browsers元素。这是一个很了不起的东西。它的设计本意可不是将服务器端控件换个标签呈现出来那么简单。先引用MSDN上的原文——
“浏览器定义文件包含各个浏览器的定义。在运行时,ASP.NET 使用请求标头中的信息来确定发出请求的浏览器的类型。随后,ASP.NET 使用 .browser 文件来确定浏览器的功能,以及如何向该浏览器呈现标记。对于希望创建可以在移动设备上查看的应用程序的 Web 开发人员,这很有用。因为这样可以利用控件适配器根据设备类型改编 ASP.NET Web 服务器控件的行为。”
MSDN是有个坏毛病,就是将答案回答的看不懂。上面这些话到底是什么意思呢?其实很简单——利用browsers元素,就可以判断浏览网页的设备(是浏览器呀?还是PDA呀?还是手机呀?如果是浏览器,那么是什么浏览器呀?IE还是FF,还是其他浏览器?如果是IE,那是那个版本呢?是IE6还是IE7?如果是手机,那么是什么牌子的手机呀?爱立信的还是摩托的?这些都能够识别出来),然后根据不同的浏览设备向浏览设备进行不同的标记呈现!
这个东西包含了两个部分:1:可以判断不同的浏览设备;2:可能向不同的浏览设备呈现不同的东西,例如可以将<asp:Label ID="Label1" runat="server"></asp:Label>在IE6中呈现为span,而在爱立信手机中程序为label。browsers的确是个很了不起的东西,因为它轻松地解决了“网页设计师”一直以来面对的一个头疼的问题——根据不同的浏览器对页面进行不同的渲染。(虽然以前用一些css hack技巧也能达到目的,但是跟这个比起来,那个的确是落后、狭隘、不值得推荐的办法)
代码实例
“光说不练假把式”,下面我们就根据实例来体会一下browsers和adapter的强大。
实例一:很简单,就是将备受非议的“服务器端控件Label打到前台为什么是span?”变成达到前台是label。
Setp1:vs2005中建一个web工程。在一个新的页面上拖个Label服务器控件。在工程中新添加一个browsers文件取名为test.browser,参看下图(十分抱歉,是日文的VS2005,虽然已经跳槽,但是现在仍然在原公司做交接工作):
点击查看大图
Setp2:删除test.browser自动生产的代码,添加我们的代码如下:
<browsers>
<browser refID="default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.Label" adapterType="LabelAdapter" />
</controlAdapters>
</browser>
</browsers>
这段代码的意思是为所有的Label服务器端控件指定名为“LabelAdapter”的适配器类型。
Setp3:创建一个名为“LabelAdapter”的类。类代码如下(解释见注释):
Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class LabelAdapter
Inherits System.Web.UI.WebControls.Adapters.WebControlAdapter
Protected Overloads ReadOnly Property Control() As Label
Get
Return DirectCast(MyBase.Control, Label)
End Get
End Property
Protected Overrides Sub RenderBeginTag(ByVal writer As HtmlTextWriter)
writer.WriteLine() '换行
writer.AddAttribute(HtmlTextWriterAttribute.Id, Control.ClientID) '添加一个id属性
If Not String.IsNullOrEmpty(Control.ControlStyle.CssClass) Then '如果设置了cssClass就添加一个Class属性
writer.AddAttribute(HtmlTextWriterAttribute.Class, Control.ControlStyle.CssClass)
End If
writer.RenderBeginTag(HtmlTextWriterTag.Label) '标签头是label
writer.Indent = writer.Indent 1 '增加缩进
End Sub
Protected Overrides Sub RenderEndTag(ByVal writer As HtmlTextWriter)
writer.Indent = writer.Indent - 1 '减少缩进
writer.RenderEndTag() '闭合标签
writer.WriteLine()
End Sub
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
RenderContent(writer)
End Sub
** Sub RenderContent(ByVal writer As HtmlTextWriter)
writer.Write(Control.Text) '打出控件的text属性内容
End Sub
End Class