Control Adapter
ASP.NET 2.0 引入了一种显示控件的方式称其为Control Adapter,Control Adapter常用在移动设备上下文中以便于控件于移动设备上显示。例如移动电话中控件内容使用WML 替代了HTML。开发人员可以使用标准ASP.NET控件开发,但是通过WML访问时就的Control Adapter。CSS Control Adapter Toolkit定义了一组使用CSS样式关联的<ul>、<div>、 and <span> 等元素替换基于table的服务器控件(如 Menu、 TreeView、and FormView) 的显示。这里将介绍Control Adapter的体系结构并讲解如何完全的改变的控件的显示方法。
构建 Control Adapter
Control Adapter本质上就是在不改变控件本身的基础上提供了一种简单的改变控件显示的方法。由于Control Adapter是为需要不同显示的客户端设计不同的显示,因此必须指定Control Adapter映射的一个.browser 文件,该文件定义了User Agent strings 以及browser capabilities。Control Adapter必须继承自抽象类System.Web.UI.Adapters.ControlAdapter,该类定义了Init, Load, PreRender, and Unload, as well as a virtual Render 等方法,和System.Web.Control有点相似。
实际上,当控件呈现时,控件基类首先判断是否存在一个Control Adapter。如果存在,则调用Adapter的Render方法;否则,将调用标准的Render方法。
创建一个Control adapter
1、选择基类。Control adapter必须继承(或间接继承)自ControlAdapter类 。如当创建一个WebControls的ControlAdapter ,选择WebControlAdapter作为其基类。
例:为BulletedList 创建一个名为BulletedListControlAdapter的 Control adapter,它将BulletedList 的选项集合重新呈现为一个有序或无序列表(<ol> 或 <ul>。首先,因BulletedList继承自 WebControls,所以选择WebControlAdapter作为Control adapter基类。而后,重载方法RenderBeginTag 、RenderEndTag 以修改<table>的开头和结尾标记。最后,重载RenderContents 方法修改呈现的内容。
BulletedListControlAdapter 完整实现结构:图 2.
namespace MsdnMagazine { public class BulletedListControlAdapter : WebControlAdapter { protected override void RenderBeginTag(HtmlTextWriter writer) { writer.WriteLine(); writer.WriteBeginTag("table"); writer.Write(HtmlTextWriter.TagRightChar); writer.Indent++; } protected override void RenderEndTag(HtmlTextWriter writer) { writer.WriteEndTag("table"); writer.Indent--; writer.WriteLine(); } protected override void RenderContents(HtmlTextWriter writer) { writer.Indent++; BulletedList bl = Control as BulletedList; if (bl != null) { foreach (ListItem i in bl.Items) { writer.WriteLine(); writer.WriteBeginTag("tr"); writer.Write(HtmlTextWriter.TagRightChar); writer.WriteLine(); writer.Indent++; writer.WriteBeginTag("td"); writer.Write(HtmlTextWriter.TagRightChar); writer.WriteLine(); writer.Indent++; writer.Write("*"); writer.Write(HtmlTextWriter.SpaceChar); writer.Write(i.Text); writer.WriteLine(); writer.Indent--; writer.WriteEndTag("td"); writer.WriteLine(); writer.Indent--; writer.WriteEndTag("tr"); writer.WriteLine(); } } writer.Indent--; } } }
2、将BulletedListControlAdapter和BulletedList关联起来,这通过指定你想关联的browsers子集。
<!-- File: MyAdapters.browser --> <browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.BulletedList" adapterType="MsdnMagazine.BulletedListControlAdapter" /> </controlAdapters> </browser> </browsers>
Any additional browser definitions or control adapters defined in this local file will be added to the collection of browsers and adapters already defined in the system browser configuration files.
在本地定义的browser或control adapters会被添加进系统的browser或control adapters集合。
3、使用控件。图 3.
<%-- File: Default.aspx --%> <%@ Page Language="C#" %> <html > <body> <form id="form1" runat="server"> <div> <asp:BulletedList ID="_bulletedList" runat="server"> <asp:ListItem Value="1">Item 1</asp:ListItem> <asp:ListItem Value="2">Item 2</asp:ListItem> <asp:ListItem Value="3">Item 3</asp:ListItem> <asp:ListItem Value="4">Item 4</asp:ListItem> </asp:BulletedList> </div> </form> </body> </html>
如果移除.browser 或在.browser 文件中没有定义control adapter 映射,则其显示的HTML代码为:
<ul id="_bulletedList"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> </ul>
使用适配器的HTML代码
<table> <tr> <td> * Item 1 </td> </tr> <tr> <td> * Item 2 </td> </tr> <tr> <td> * Item 3 </td> </tr> <tr> <td> * Item 4 </td> </tr> </table>
这有几点需要注意的,首先并不是所有BulletedList 的属性都出现在BulletedListControlAdapter内。在BulletedListControlAdapter里面仅仅包含了BulletedList 的items 集合。CSS Control Adapters 放弃了控件的大部分数据,而是选择了一组特点的显示样式。
其次、BulletedListControlAdapter 并没有将适配器根据不同的用户而关联不同的browser ,而是将其应用到所有的浏览器。如何这个Adapter的设计目的是在Mobile中使用,而在HTML中使用标准控件显示,则需要定一具体的Browser 。
Browser 设别
ASP.NET 2.0中浏览器设备<browserCaps>已经从machine.config 和 web.config 移出,而是放进了一个.browser 文件。尽管仍然支持<browserCaps>元素,但是较好的方式是将其放到App_Browsers 文件夹或%SYSTEM%\Microsoft.NET\Framework\v2.0.50727\Config\Browsers下的.browser 文件内。.browser 文件不仅仅是关联control adapters,它还通过request 请求的Request.Browser 属性暴露了HttpBrowserCapabilities类。HttpBrowserCapabilities类包含了浏览器名称、cookies、JavaScript以及其它属性。为使用该类,每个.browser 文件包含了一个或多个<browser>节点。典型的每个<browser>节点包含一个identification 子节点,其下包含一个正则表达式,这个正则表达式(User Agent string )用来判断指定浏览器是否可以调用HttpBrowserCapabilities类对象。例如:定义IE浏览器:
<browsers> <browser id="IE" parentID="Mozilla"> <identification> <userAgent match="^Mozilla[^(]*\([C|c]ompatible;\s*MSIE (???£¤version??£¤(???£¤major??£¤\d+)(???£¤minor??£¤\.\d+)(???£¤letters??£¤\w*)) (???£¤extra??£¤[^)]*)" /> <userAgent nonMatch="Opera|Go\.Web|Windows CE|EudoraWeb" /> </identification> <capabilities> <capability name="browser" value="IE" /> <capability name="extra" value="${extra}" /> <capability name="isColor" value="true" /> <capability name="letters" value="${letters}" /> ...
浏览器类型级别
浏览器使用<browser>中的parentID来分级别。为了使用parentID 引用另一个<browser>元素,其父的正则表达式必须满足。其跟节点是"Default", 该节点匹配所有的user agent strings ,并具有浏览器要求的最少功能,其它任何浏览器均是其子孙节点。