asp.net 在前面的文章中我曾经介绍过DeviceSpecific/Choice构造和设备筛选器,那时我们还是在ASP.NET 移动页面的HTML视图下或站点程序的Web.Config文件中通过手动编码来定义设备筛选器和DeviceSpecific/Choice构造。但是,如果你使用的是Visual Studio 2005的话,我们可以直接采用一种便捷的、可视化的方式去定义DeviceSpecific/Choice构造和设备筛选器,避免了在程序中采用手动编码这样繁杂的实现过程,而且因为开发人员没有直接的键入代码,也就不容易出现代码的拼写和语法错误。
提示:在Visual Studio 2005工具箱的"移动Web窗体"选项卡中包含一个名为DeviceSpecific的控件,你可以拖拽此控件到一个Form控件或Panel控件中。而后你将这个页面切换到HTML视图时,你会发现对应的Form控件或Panel控件中将包含DeviceSpecific/Choice的构造语法。有一点需要注意的是,你不能想当然地认为拖拽一个DeviceSpecific控件到其他的ASP.NET移动控件中也会实现上述的DeviceSpecific/Choice构造。只有当你定义一个属性重写或为列表控件定义一个模板化选项时,才会自动地在这些控件里添加一个DeviceSpecific/Choice构造。DeviceSpecific控件仅适用于在Form控件和Panel控件中以一种可视化的方式定义模板化选项。
创建和应用设备筛选器
在ASP.NET移动页面上选中一个控件后,在属性窗口的"设备特定"栏中可以看到(AppliedDeviceFilters)项,我们可以点击其右侧空白处的省略号按钮,这时会弹出"已应用的设备筛选器"对话框。原本该对话框的首要目的是编辑完控件的属性后,为这种状态下的控件应用设备筛选器,但是它也可以让你定义新的设备筛选器。并且这些定义好的设备筛选器可以应用于整个站点程序和所有的控件中,ASP.NET会自动将这些新定义的设备筛选器存储在站点程序的Web.Config文件中。
在上图"可用的设备筛选器"下拉列表中,列举出了当前正在编辑属性的控件所有可用的设备筛选器。该对话框的下方列表中,显示了当前正在编辑属性的控件已应用的设备筛选器。 如果你要新建一个设备筛选器的话,可以点击对话框上的"编辑"按钮。这时会弹出"设备筛选器编辑器",如图所示:
在该对话框中,你将可以在右侧的"设备筛选器"列表中看到当前站点程序中已存在的设备筛选器。当你在上述的"设备筛选器"列表中任选一个类型为"相等比较"的设备筛选器,该设备筛选器对应的属性就会在"比较"下拉列表框和"参数"文本框中显现出来。
所有添加一个"相等比较"的设备筛选器,你按照如下的步骤即可实现:
1. 点击"设备筛选器编辑器"对话框上的"新建设备筛选器"按钮。
2. 为这个新建的设备筛选器键入一个合适的名称。
3. 该设备筛选器的"类型"选择"相等比较"。
4. 在"比较"下拉列表框中,键入或选择要与对话框中"参数"文本框中的值进行比较的MobileCapabilities类中的某个属性。
5. 在"参数"文本框中输入参数值,当一个MobileCapabilities对象对应的属性值和该参数相等时就将返回"true"值。
提示:就拿上图来说是一个名为isWML11的设备筛选器,在这里我们选择要比较的属性是PreferredRenderingType,也就是说如果该设备筛选器的PreferredRenderingType属性对应的值等于下面"参数"文本框的值"wml11",那么该设备筛选器就返回一个true值。
创建一个类型为"鉴别委托"的设备筛选器的过程和上面相等比较设备筛选器的创建过程是类似的,惟一的不同就是鉴别委托的设备筛选器不是在"比较"下拉列表框和"参数"文本框键入或选择相应的内容,取而代之的是你需要在"类型"文本框输入包含自定义委托的类名和.DLL程序集名,而在"方法"文本框输入的是实际的委托方法名。
在上一篇文章《设备筛选器的定义及实现》描述了一个名为UseLargeGIF委托方法,如果你需要使用该方法来鉴别一幅图片是不是大型GIF图片的话,你需要在类型文本框中输入"MyEvaluators.CustomEvals,MyEvaluators",而在"方法"处输入"UseLargeGif"。当你为站点程序定义好了所有的设备筛选器后,你可以将它们应用到任何一个希望实现属性重写的控件中。所有你新定义的设备筛选器都会在"设备筛选器编辑器"下拉列表中显现出来。
为控件应用设备筛选器
在"已应用的设备筛选器"对话框中,选择将要给一个控件应用的设备筛选器,并点击"添加到列表"按钮将这个可用的设备筛选器添加到"已应用的设备筛选器"列表框中。而后你还可以点击该对话框上的上下箭头来调整这些设备筛选器的位置。名为(Default)的设备筛选器是默认的选择,所有它返回的总是true值。因此,(Default)设备筛选器的次序必须位于所有设备筛选器的下方(也就是"已应用的设备筛选器"列表框的最底端位置)。具体的情形如下图所示:
该图显示的是为一个label控件应用四个设备筛选器,相应地你应该知道这种情形下由Visual Studio 2005自动生成的DeviceSpecific/Choice构造代码如下:
<mobile:Form id="Form1" runat="server"> <mobile:Label ID="Label1" Runat="server"> <DeviceSpecific> <Choice Filter="isPocketIE" /> <Choice Filter="isHTML32" /> <Choice Filter="isCHTML10" /> <Choice /> </DeviceSpecific> </mobile:Label> </mobile:Form> |
也就是说四个设备筛选器的次序也就是DeviceSpecific/Choice构造中的<Choice>元素的相应次序。
属性重写详解
<DeviceSpecific> 和<Choice>元素
所有继承自System.Web.UI.MobileControl的ASP.NET移动服务器控件,在其代码声明中都可以包含一个<DeviceSpecific>元素。我在前面提及过,一个<DeviceSpecific>元素可以包含任意个<Choice>元素。一般来说,<Choice>元素的语法如下:
<Choice Filter="filterName" xmlns="urlToSchema" <!-属性重写选项--!> > <!-模板化选项--!> </Choice> |
下表是<Choice>常用的一些属性和子元素。
属性/子元素 | 说明 |
Filter | 对照前面的<Choice>元素的语法,FilterName必须为一个可用的、在站点Web.Config文件<deviceFilters>节点处定义的设备筛选器的名称。注意,设备筛选器的名称是大小写敏感的,isHTML32和ishtml32是两个不同是设备筛选器。如果你在<Choice>元素中没有定义Filter属性,那么在<Choice>元素就将成为默认的选择,为此<Choice/>在设备筛选器列表中的排列位置是最后的。 |
Property overrides | 你可用在DeviceSpecific/Choice构造中为控件的属性设置值。也就是说你可以在每个<Choice>元素中为控件对应不同的设备筛选器设置不同的属性值。例如我们在前面的示例中设置了四个设备筛选器(其中一个是默认的),如果你在<Choice>元素中为每个设备筛选器都设置了不同的label控件的Text属性。那么当某个设备筛选器返回true值的话,那么在该设备筛选器对应Text属性文本值就会重写其他设备筛选器中的Texe属性文本值。 |
xmlns | 该属性一般是不用开发人员来指定的,Visual Studio 2005会自动检测模板中使用的是什么标记语言,而后Visual Studio 2005就会将该属性插入到相应的<Choice>元素中。所以站点无需直接对该属性进行操作,你也没有必要为该属性赋值。 |
Template elements | 使用这个属性指定一些模板化的控件-例如Form、Panel、List和ObjectList控件,它允许页面在呈现时将你定义的内容整合到这些控件中。 |
你可以在<DeviceSpecific>元素中使用一个不指定Filter属性的<Choice>元素, 这就是我上面所说的默认的<Choice>元素。你也可以不定义这样一个默认的<Choice>元素,但是一旦你定义的话,就一定要将该默认的元素放置在整个<Choice>元素列表的最末端。这是因为ASP.NET是按顺序来鉴别<Choice>元素的,当某个特定的设备请求移动Web页面时,将会应用第一个返回true的<Choice>元素。而默认的<Choice>元素总是返回true值,所以放置到整个元素列表最前面的话就将导致其他的<Choice>元素失效。
列表列举了使用<Choice>元素的不同方法,在本示例中使用它来进行属性重写和定义<HeaderTemplate>和<FooterTemplate>(这些都是Form控件中常用的模板)。
<% Page Inherits="System.Web.UI.MobileControls.MobilePage" Language="C#" %> <% Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls" Assembly="System.Web.Mobile" %> <mobile:Form runat="server"> <DeviceSpecific> <Choice Filter="isHTML32"> <!-当设备支持HTML 3.2标记语言时,使用两个模板构建页面,且在页眉模板中使用图片--!> <HeaderTemplate> <table width="100%" height="100%" cellspacing="1"> <tr><td bgcolor="#003366"> <img src="http://www.webjx.com/htmldata/2006-10-16/sportsextra.gif"> </td></tr> <tr><td bgcolor="#cccccc" valign="top" height="100%"> </HeaderTemplate> <FooterTemplate> </td></tr> <tr><td bgcolor="#003366" height="4"></td></tr> </table> </FooterTemplate> </Choice> <Choice> <!-默认的元素。当设备不支持HTML 3.2标记语言时,只在页眉模板 中使用SPORTS EXTRA!文本--!> <HeaderTemplate> <mobile:Label runat="server" StyleReference="title" Text="SPORTS EXTRA!" /> </HeaderTemplate> </Choice> </DeviceSpecific> <mobile:Label runat="server" Font-Size="Small" Font-Name="Arial"> Welcome to our mobile Sports Extra Web site. Check here for up-to-the minute sports news as it happens! <DeviceSpecific> <Choice Filter="isWML11" Text="Welcome to LIVE results!"/> <!-当设备支持WML 1.1标记语言时,Label控件的Text属性值为"Welcome to LIVE results!"--!> <Choice Filter="isCHTML10" ForeColor="Red" Text="Welcome to LIVE results!"> <!-当设备支持的是CHTML 1.0标记语言时,Label控件的Text属性值依然为 "Welcome to LIVE results!",但是字体的颜色是红色--!> </Choice> </DeviceSpecific> </mobile:Label> </mobile:Form> |
下面是站点程序的Web.Config文件中定义的设备筛选器:
<configuration> <system.web> <deviceFilters> <filter name="isHTML32" compare="PreferredRenderingType" argument="html32" /> <filter name="isWML11" compare="PreferredRenderingType" argument="wml11" /> <filter name="isCHTML10" compare="PreferredRenderingType" argument="chtml10" /> </deviceFilters> </system.web> </configuration> |
Form控件中包含一个<DeviceSpecific>元素,如果客户端设备支持HTML 3.2,那么就会在Form控件中插入一个HeaderTemplate(页眉模板)和一个FooterTemplate(页脚模板),并且这两个模板中的HTML标记合起来就使得该页面形成一个表格布局。在这个表格中我们使用了<img>HTML标签将一幅图片填充到表格的第一行。
对位于Form控件中的DeviceSpecific/Choice构造的第二个<Choice>元素,并不存在Filter属性,所以它就是默认的<Choice>元素。如果对当前的请求isHTML32设备筛选器返回的是false值,那么程序将使用仅包含一个Label控件的<HeaderTemplate>来呈现页面。
除此之外,Form控件中还包含了一个使用DeviceSpecific/Choice构造的Label控件,而使用DeviceSpecific/Choice构造的主要目的就是属性重写。Label控件默认状态下的文本值为一段长的字符串"Welcome to our mobile Sports Extra Web site. Check here for up-to-the minute sports news as it happens!"。然而,在一些小屏幕的设备来说,例如支持WML 1.1,CHTML 1.0标记语言的设备(也就是说对isWML11、isCHTML10设备筛选器来说返回true),上述的字符串将缩短为"Welcome to LIVE results!"。而且在i-mode的设备(就是支持CHTML 1.0的设备)上,Text属性和ForeColor属性均被重写。
下面两图分别是上述程序在Pocket Internet Explorer和openwave仿真程序中的实际显示效果。从图可以看出,在Pocket Internet Explorer中,页面的布局是采用表格的形式,而且因为Pocket Internet Explorer支持HTML 3.2标记语言,所以DeviceSpecific/Choice构造的第一个<Choice>元素返回true值,为此会使用<HeaderTemplate>和<FooterTemplate>两个模板,并且label控件显示的是长字符串文本。
使用属性重写为自定义特定设备的呈现
属性重写是一种在DeviceSpecific/Choice构造中为不同的客户端设备设置不同的控件属性值的方法,也就是说可以根据不同的设备进行不同的呈现。
每个ASP.NET移动控件都可以包含一个DeviceSpecific/Choice构造。在<DeviceSpecific>元素中的每个<Choice>元素依次进行鉴别,而第一个鉴别为true的<Choice>元素将应用到包含该构造的控件上。在上一篇文章《设备筛选器的定义及实现》中,我曾经举了一个使用属性重写的具体的实例,就是使用image控件为特定的移动设备呈现该设备支持格式的图片,代码如下:
<mobile:Image runat="server" id="myImages" AlternateText="Northwind Corp."> <DeviceSpecific> <Choice Filter="isHTML32" ImageUrl="Northwindlogo.gif"/> <Choice Filter="isWML11" ImageUrl="Northwindlogo.wbmp"/> </DeviceSpecific> </mobile:Image> |
当客户端设备请求包含该控件的页面时,ASP.NET会自动使用该设备对应的MobileCapabilities对象来解析<Choice>元素。如果isHTML32返回true的话,那么image控件就将使用Northwindlogo.gif进行呈现。如果isWML11返回true,就使用Northwindlogo.wbmp图片。如果上述的两个设备筛选器均不为true 的话,那么ImageUrl属性就处于未定义状态,也就是说将使用image控件的AlternateText属性值"Northwind Corp."文本进行替代。
提示:在image控件中使用的两个设备筛选器均已经在Web.Config文件中进行了定义,如果你的站点程序还没有Web.Config文件的话,可以在"解决方案资源管理器"中通过右键菜单的"添加新项"-"移动Web配置文件"方式手动进行添加。
在上面的示例中演示了DeviceSpecific/Choice构造的基本用法:如果特定的设备筛选器为true的话,将对包含该构造的控件进行属性重写。属性重写主要可以用来实现:
1. 使用不同的图片文件:当一个客户端设备支持不同的图片格式,你可以采用属性重写实现选择何种图片进行呈现。
2. 因为设备显示屏大小而对字符串进行调整:你可以在一些大屏幕的设备上使用长字符串,而在小屏幕的设备使用缩减的字符串。
3. 支持多语言的程序:你可以根据客户端设备使用的首选语言,为控件的Text属性设置以该语言对应的文本。
4. 为特定设备自定义样式属性:当客户端设备在呈现控件时,ASP.NET会根据该设备支持的特性使用不同的字体或颜色。除此之外,你还可以为特定的设备使用不同的样式属性。 在下一篇文章中将会介如何使用DeviceSpecific/Choice构造和模板化控件,为客户端设备使用特定的标记语言。
在Visual Studio 2005中采用可视化的方式定义属性重写
Visual Studio 2005提供了一种可视化的方式来定义和应用设备筛选器,属性重写也不例外。当你想为某个控件应用属性重写时必须首先为该控件应用一个设备筛选器。给控件应用设备筛选器我在前面已经介绍过了,为了你巩固前面的知识,这里就将实现属性重写的整个过程均列举出来:
1. 通过"文件"-"新建网站"-"ASP.NET网站"新建一个站点。
2. 删除"Default.aspx"文件,在"解决方案资源管理器"中通过右键菜单的"添加新项"-"移动Web窗体"命令添加一个ASP.NET 移动页面。
3. 依然在"解决方案资源管理器"中通过右键菜单的"添加新项",通过"移动Web配置文件"为站点添加一个已包含若干个设备筛选器的Web.Config文件。
4. 拖拽一个Label控件中Form控件中,选中Label控件,并在属性窗口的(AppliedDeviceFilters)项处点击右侧的省略号按钮。
5. 在弹出的"已应用的设备筛选器"对话框中,通过选择"可用的设备筛选器"下拉列表框的各项将你想添加的设备筛选器通过"添加到列表"按钮逐个添加到"已应用的设备筛选器"列表中,最后点击"确定"按钮,这样就为该控件应用了设备筛选器。下图是我在该示例中添加的4个设备筛选器。
6. 选中Label控件,在属性窗口的(Property Overrides)项右侧点击省略号按钮,这时会弹出"属性重写"对话框。
7. 我们可通过"已应用的设备筛选器"下拉列表来查看该控件当前已应用的设备筛选器,现在我们就先选择isPocketIE("")为该设备筛选器设置属性重写,在本例中我们仅对该控件的Text属性进行重写,为此我们可用在Text属性处填写"使用isPocketIE设备筛选器进行属性重写"。各个设备筛选器的Text属性设置如下:
8. 为Label控件设置好各个设备筛选器的属性重写后,当客户端设备请求该页面时,如果浏览器是Pocket Internet Explorer的话,Label控件上将显示"使用isPocketIE设备筛选器进行属性重写"文本。如果是支持html 3.2标记语言的浏览器,Label控件上显示的是"使用isHTML32设备筛选器进行属性重写"。
该页面最终的代码如下:
<mobile:Form id="Form1" runat="server"> <mobile:Label ID="Label1" Runat="server"> <DeviceSpecific> <Choice Filter="isPocketIE" Text="使用isPocketIE设备筛选器进行属性重写" /> <Choice Filter="isHTML32" Text="使用isHTML32设备筛选器进行属性重写" /> <Choice Filter="isCHTML10" Text="使用isCHTML10设备筛选器进行属性重写" /> <Choice Text="使用默认的设备筛选器进行属性重写" /> </DeviceSpecific> </mobile:Label> </mobile:Form> |