移动Web窗体设计
ASP.NET移动Web窗体页是一种专用的移动Web窗体页。与任何其他Web窗体页一样,移动Web窗体页也是带.aspx文件扩展名的文本文件。移动Web窗体页包含一组移动Web窗体控件,这些控件是ASP.NET服务器控件,它们可以适应性地呈现给受支持的移动设备。可以使用与设备无关的属性、方法和事件,对移动页和控件进行编程。当受支持的设备请求移动Web窗体页时,页和控件会自动产生适合于该设备的呈现。
当设计ASP.NET移动Web应用程序时,最好将用户界面(UI)的定义与业务逻辑及数据存储区分开。移动Web窗体页和ASP.NET Web窗体页一样,能方便地分开呈现和逻辑。例如,可以将用户界面定义放在一个.aspx文件中,将关联的事件处理程序和其他用户界面代码,放在同一个文件中或一个代码隐藏页中。除此还可以将业务逻辑代码放在用所选择的语言(公共语言运行库支持的语言)编写的单独的类中。将呈现和逻辑分开的一个主要优点是,可以重复使用用于桌面和移动Web应用程序的代码。如果已编写了支持桌面Web浏览器的ASP.NET Web应用程序,则可以在移动Web应用程序中重复使用业务逻辑代码。
19.4.1 简易的移动Web窗体
清单19-1中的示例演示了一个短小、简易的移动Web窗体页,其中包含一些文本和一个移动控件。源代码显示的标题指令必须位于每个移动Web窗体页的开头,每个移动Web窗体页都必须具有以下将它标识为移动页的标准标头指令。其中“Language="VB"”,则根据页所使用的语言而异。
清单19-1 简易的移动Web窗体
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="SimpleForm.aspx.vb"
Inherits="SimpleForm" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form runat="server">
你好,中国!<br />
<mobile:Label runat="server" Text="你看到我的存在了吗?" />
</mobile:Form>
</body>
</html>
移动Web窗体页中的每个移动控件标记,都必须包括“runat="server"”属性。每一页至少包含一个移动窗体,由“<mobile:Form>”标记指出来。“CodeFile="Default.aspx.vb"”指定了移动Web页面所对应的代码文件。图19-3显示了清单19-1所演示的简易移动Web窗体。
图19-3 简易的移动Web窗体
19.4.2 放置多个移动Web窗体
在普通的ASP.NET Web窗体页上,每页只能包含一个窗体。但是由于移动设备的屏幕通常较小,因此在一个移动Web窗体页上允许定义多个窗体。这样有几个好处:
· 避免了大量的小页,从而可以控制Web站点的复杂性。
· 可以像组织桌面Web应用程序那样来组织移动Web应用程序,因为可以处理与包含多个窗体的单个移动页。
· 可以利用移动Web窗体所提供的页级功能,例如自动维护页状态(称为视图状态)以及适应能够在单个响应中接收多个屏幕的设备。
当客户端第一次访问某页时,默认情况下显示第一个窗体。可以通过设置移动页的ActiveForm属性以编程方式导航到其他窗体,也可以允许用户通过使用Link控件导航到窗体。清单19-2中的示例演示如何将多个窗体放置在单个移动Web窗体页中,以及如何使用Link控件来允许用户在窗体间定位。图19-4显示了清单19-2所演示示例运行时的Web页面。
清单19-2 在一个页上放置多个窗体
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="MultipleForms.aspx.vb"
Inherits="MultipleForms" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form runat="server" id="FirstForm">
<mobile:Label runat="server" StyleReference="title">这是第一个窗体</mobile:Label>
<mobile:Link runat="server" NavigateURL="#SecondForm">下一个窗体</mobile:Link>
</mobile:Form>
<mobile:Form runat="server" id="SecondForm">
<mobile:Label runat="server" StyleReference="title">这是第二个窗体</mobile:Label>
<mobile:Link runat="server" NavigateURL="#FirstForm">上一个窗体</mobile:Link>
</mobile:Form>
</body>
</html>
图19-4 显示多个移动Web窗体
19.4.3 响应控件事件
ASP.NET移动控件公开了一个包含属性、方法和事件的对象模型。可以使用该对象模型非常方便地修改页面和与页面交互。移动控件的对象模型不依赖于设备,因此可以通过统一方式与其进行交互,而与目标设备无关。清单19-3中的示例演示在移动Web页面中如何处理Command控件的Click事件。当代码收到此事件时,它以编程方式定位到另一窗体。新激活的窗体触发Activate事件,可以使用该事件初始化窗体。清单19-4说明了页面所对应的代码文件ControlEvents.aspx.vb中的实现代码。
清单19-3 Command控件的Click事件
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ControlEvents.aspx.vb"
Inherits=" ControlEvents" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form id="FirstForm" runat="server">
<mobile:Label ID="lblQuestion" Runat="server">你是谁?</mobile:Label>
<mobile:TextBox ID="tbName" Runat="server">
</mobile:TextBox>
<mobile:Command ID="cmdOK" Runat="server"> 确 定 </mobile:Command>
</mobile:Form>
<mobile:Form ID="SecondForm" Runat="server">
<mobile:Label ID="lblResult" Runat="server">Label</mobile:Label>
</mobile:Form>
</body>
</html>
清单19-4 ControlEvents.aspx.vb
Partial Class ControlEvents
Inherits System.Web.UI.MobileControls.MobilePage
Dim sInputName As String
Protected Sub cmdOK_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles cmdOK.Click
sInputName = String.Format("嗨!{0},你好!", tbName.Text)
Me.ActiveForm = SecondForm
End Sub
Protected Sub SecondForm_Activate(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles SecondForm.Activate
lblResult.Text = Server.HtmlEncode(sInputName)
End Sub
End Class
图19-5显示了清单19-3所演示示例运行时的Web页面。
图19-5 在移动Web页面中处理Command控件的Click事件
19.4.4 显示菜单
移动用户界面的典型特性是有菜单,它允许用户轻松浏览页选项。在移动Web窗体页面上,构建菜单的一种常用方法是使用List移动控件。清单19-5中的示例演示使用List移动控件在移动Web窗体中显示菜单。当用户单击一个选项时,将触发List移动控件的ItemCommand事件。页面所对应的代码使用单击选择的选项改变第二个窗体的内容,然后定位到第二个窗体。清单19-6说明了页面所对应的代码文件Menu.aspx.vb中的实现代码。
清单19-5 在移动Web窗体中显示菜单
<%@ Page Language="VB" AutoEventWireup="false" CodeFile=" Menu.aspx.vb"
Inherits=" ControlEvents" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form ID="FirstForm" Runat="server">
<mobile:Label ID="lblCityList" Runat="server">城市列表</mobile:Label>
<mobile:List ID="lstCity" Runat="server">
<Item Text="北京" Value="中国" />
<Item Text="上海" Value="中国" />
<Item Text="广州" Value="广东" />
<Item Text="深圳" Value="广东" />
<Item Text="长沙" Value="湖南" />
<Item Text="青岛" Value="山东" />
</mobile:List>
</mobile:Form>
<mobile:Form ID="SecondForm" Runat="server">
<mobile:Label ID="lblCity" Runat="server">
</mobile:Label>
</mobile:Form>
</body>
</html>
清单19-6 Menu.aspx.vb
Partial Class Menu
Inherits System.Web.UI.MobileControls.MobilePage
Protected Sub lstCity_ItemCommand(ByVal sender As Object, ByVal e As _
System.Web.UI.MobileControls.ListCommandEventArgs) Handles lstCity.ItemCommand
lblCity.Text = String.Format("{1} {0}", e.ListItem.Text, e.ListItem.Value)
Me.ActiveForm = SecondForm
End Sub
End Class
图19-6显示了清单19-5所演示示例运行时的Web页面。
图19-6 在移动Web窗体中显示菜单
19.4.5 显示文本
在移动Web窗体上有3种显示文本的方法。一种是将文本放置在Label控件中,这种方法适合显示少量文本的情况。一种是将文本直接放置在窗体上。将文本放置在TextView控件中,这种方法适合显示大量文本的情况。TextView控件可以动态设置包含一些通用标记的文本。支持的标记有<b>、<i>、<p>、<br>和<a>。当在单个窗体上放置大量文本时,可以通过将Paginate属性设置为true来使用窗体的分页功能。窗体将根据目标设备的特性,对其内容进行分页。
清单19-7中的示例显示了TextView控件的运行情况。在Pocket PC设备上,文本占用一页(但它可以滚动)。在基于WML的移动电话上,文本在多个屏幕上呈现。在这两种情况中,TextView控件都能自动为用户提供在文本页之间浏览的用户界面。图19-7显示了清单19-7所演示示例运行时的Web页面。
清单19-7 在窗体上显示大量文本
<%@ Page Language="VB" AutoEventWireup="false" CodeFile=" DisplayText.aspx.vb"
Inherits=" DisplayText" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form id="Form1" runat="server" Paginate="True" BackColor="#E0E0E0">
<mobile:Label ID="Label1" Runat="server" Font-Bold="True" Font-Size="Large" ForeColor="Teal">第18章 移动Web开发</mobile:Label>
<mobile:TextView ID="TextView1" Runat="server" ForeColor="Teal">……</mobile:TextView>
</mobile:Form>
</body>
</html>
图19-7 在窗体上显示大量文本
19.4.6 允许用户打电话
某些Pocket PC设备(如Pocket PC智能手机)可以在用户进行选择时打出电话。PhoneCall控件可以为应用程序封装此操作,这样,当从能打电话的设备上访问该应用程序时,将显示一个用于执行此操作的用户界面。当从不能打电话的设备上访问该应用程序时,会显示一个标签文本或一个链接。清单19-8中的示例演示了PhoneCall控件的一种简单用法,它可使能打电话的设备能够通过链接打出电话,并在不能打电话的设备上显示包含电话号码和超级链接的文本。图19-8显示了清单19-8所演示示例运行时的Web页面。
清单19-8 PhoneCall控件
<%@ Page Language="VB" AutoEventWireup="false" CodeFile=" DisplayText.aspx.vb"
Inherits=" DisplayText" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form id="Form1" runat="server"><br /><br /><br /><br /><br />
<mobile:PhoneCall ID="pcDemo" Runat="server"
AlternateUrl="http://support.microsoft.com/" PhoneNumber="(086)021-96081318">
微软客户服务支持热线
</mobile:PhoneCall>
</mobile:Form>
</body>
</html>
图19-8 PhoneCall控件
19.4.7 用户输入
许多ASP.NET移动Web窗体控件都支持用户输入。当设计允许用户输入的窗体时,可以将一个或多个用户输入控件以及其他移动控件(如标签)放在窗体中。对于大多数允许用户输入窗体来说,还需要在窗体上放置Command控件让用户将输入提交回服务器。设计移动Web界面的输入功能时,同样适用本书第5章介绍的界面设计原则,应尽量避免用户直接输入的次数和输入量。因此,在设计移动Web界面的输入功能时,应尽量多地使用List控件和SelectionList控件来替代使用TextBox控件接收用户输入。List移动控件支持下列3种呈现样式:
(1)None 每个列表项都按原样显示。
(2)Bulleted 带项目符号,每个列表项都带有项目符号。
(3)Numbered 带编号,每个列表项都带有编号。
清单19-9中的示例演示以交互输入方式查看List控件所有支持的呈现样式。清单19-10说明了页面所对应的代码文件List.aspx.vb中的实现代码。
清单19-9 使用List控件输入
<%@ Page Language="VB" AutoEventWireup="false" CodeFile=" List.aspx.vb"
Inherits=" List" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form id="Form1" runat="server">
<mobile:Label ID="Label1" Runat="server" Font-Bold="True">List移动控件</mobile:Label>
<mobile:List ID="ListDemo" Runat="server">
<Item Text="None(无)" Value="None" />
<Item Text="Bulleted(带项目符号)" Value="Bulleted" />
<Item Text="Numbered(带编号)" Value="Numbered" />
</mobile:List>
</mobile:Form>
</body>
</html>
清单19-10 List.aspx.vb
Partial Class List
Inherits System.Web.UI.MobileControls.MobilePage
Protected Sub ListDemo_ItemCommand(ByVal sender As Object, ByVal e As _
System.Web.UI.MobileControls.ListCommandEventArgs) Handles ListDemo.ItemCommand
Dim text As String = e.ListItem.Value
ListDemo.Decoration = CType(System.Enum.Parse(GetType(MobileControls.ListDecoration), _
text, True), MobileControls.ListDecoration)
End Sub
End Class
图19-9显示了清单19-9所演示示例运行时的Web页面。
图19-9 List移动控件
SelectionList控件的数据功能与List控件很相似。SelectionList控件的不同之处在于它被独占使用以表示窗体中的选定项,并且要求其他控件(如Command控件)提交选定项。除了支持单个选定项之外,SelectionList控件还支持多个选定项。SelectionList移动控件支持下列5种呈现样式:
(1)DropDown 单个选定项,列表显示为下拉列表框。
(2)ListBox 单个选定项,列表显示为列表框。
(3)Radio 单个选定项,列表显示为一组选项按钮。
(4)MultiSelectListBox 多个选定项,列表显示为列表框。
(5)CheckBox 多个选定项,列表显示为一组复选框。
清单19-11中的示例说明以CheckBox多选模式使用SelectionList控件进行输入,以及如何使用选定项信息。清单19-12说明了页面所对应的代码文件SelectionList.aspx.vb中的实现代码。
清单19-11 使用SelectionList控件输入
<%@ Page Language="VB" AutoEventWireup="false" CodeFile=" SelectionList.aspx.vb"
Inherits=" SelectionList" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:Form id="Form1" runat="server">
<mobile:Label ID="Label1" Runat="server" Font-Bold="True">SelectionList移动控件</mobile:Label> <br />
<mobile:SelectionList ID="SelectionList1" Runat="server" SelectType="CheckBox">
<Item Text="北京" Value="北京" />
<Item Text="上海" Value="上海" />
<Item Text="广州" Value="广州" />
<Item Text="长沙" Value="长沙" />
<Item Text="青岛" Value="青岛" />
</mobile:SelectionList> <br />
<mobile:Command ID="cmdOK" Runat="server"> 确 定 </mobile:Command>
</mobile:Form>
</body>
</html>
清单19-12 SelectionList.aspx.vb
Partial Class SelectionList
Inherits System.Web.UI.MobileControls.MobilePage
Protected Sub cmdOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdOK.Click
Dim citiesChosen As String = ""
Dim item As MobileControls.MobileListItem
For Each item In CityList.Items
If (item.Selected) Then
If (citiesChosen.Length > 0) Then
citiesChosen = citiesChosen & ","
End If
citiesChosen = citiesChosen & item.Text
End If
Next
If (citiesChosen.Length = 0) Then
citiesChosen = "未选择任何城市……"
End If
lblResult.Text = citiesChosen
ActiveForm = SecondForm
End Sub
End Class
图19-10显示了清单19-11所演示示例运行时的Web页面。
图19-10 SelectionList移动控件
19.4.8 输入验证
ASP.NET提供了一种强大的验证机制,使用它可以检查输入是否有错误,并且在必要时向用户显示消息。ASP.NET移动Web窗体提供了5个不同的用于验证输入的移动控件,它们分别是:
(1)RequiredFieldValidator 验证关联的输入控件的值是否不同于其初始值。
(2)CompareValidator 使用可指定的比较运算符来比较某控件中的特定字段与另一控件中的特定字段,并以此来确定有效性。
(3)RangeValidator 验证另一控件值是否在允许的范围内。
(4)RegularExpressionValidator 提供用于验证另一控件的值是否与所提供的正则表达式相匹配的控件功能。
(5)CustomValidator 提供可以对另一个控件执行自定义验证的控件。
移动验证控件使用有限的移动控件子集。表19-6显示了可用于这5个控件进行验证的输入控件及其属性。
表19-6 可用于验证的移动输入控件
控件 | 验证属性 |
TextBox | Text |
SelectionList | SelectedIndex |
注意,为了在窗体上进行验证,导致提交窗体的控件的CausesValidation属性必须设置为true。当前惟一适用于这一点的控件是Command控件,默认情况下其CausesValidation属性为true。
19.4.9 自动分页
ASP.NET移动Web窗体的一个主要功能,就是能够根据目标设备的屏幕大小将内容分页。窗体分页的处理是通过结合服务器端分页,和客户端上执行的自动分页共同完成。并非所有窗体都适合自动分页。通常情况下,显示大量文本或许多列表项的窗体可以从分页中获益。前面几节包含了这类启用了分页的窗体的示例。要为窗体启用分页,必须将窗体的Paginate 属性设置为true,然后窗体会自动将其内容分页。
19.4.10 设备筛选器
要创建并使用设备特定的内容,必须首先为应用程序配置一组设备筛选器。ASP.NET页框架使用这些设备筛选器,为目标设备选择设备特定的内容。设备筛选器不一定是排他性的,一个设备可以匹配多个筛选器。
要定义设备筛选器,需要在应用程序的web.config文件中创建<deviceFilters>节,并将<filter>元素添加到其中。清单19-13显示了web.config文件中基本的设备筛选器配置。
清单19-13 web.config文件中基本的设备筛选器配置
<deviceFilters>
<filter name="isJPhone" compare="Type" argument="J-Phone"/>
<filter name="isHTML32" compare="PreferredRenderingType" argument="html32"/>
<filter name="isWML11" compare="PreferredRenderingType" argument="wml11"/>
<filter name="isMME" compare="Browser" argument="Microsoft Mobile Explorer"/>
<filter name="isMyPalm" compare="Browser" argument="MyPalm"/>
<filter name="isPocketIE" compare="Browser" argument="Pocket IE"/>
<filter name="isUP3x" compare="Type" argument="Phone.com 3.x Browser"/>
<filter name="isUP4x" compare="Type" argument="Phone.com 4.x Browser"/>
<filter name="isEricssonR380" compare="Type" argument="Ericsson R380"/>
<filter name="isNokia7110" compare="Type" argument="Nokia 7110"/>
<filter name="supportsCookies" compare="Cookies" argument="true"/>
<filter name="supportsJavaScript" compare="Javascript" argument="true"/>
<filter name="supportsVoiceCalls" compare="CanInitiateVoiceCall" argument="true"/>
</deviceFilters>
在清单19-13中,name属性指定筛选器的名称,可以使用此名称在移动Web窗体页中引用该筛选器。其余属性定义如何测试筛选器。在针对筛选器测试设备时,框架将根据argument属性指定的值检查compare属性中命名的设备功能。可用的功能集可以在System.Web.UI.Mobile.Controls.MobileCapabilities类的参考资料中找到。
19.4.11 DeviceSpecific和Choice
若要在页面上以声明方式定义设备特定的内容,则可以使用DeviceSpecific控件。可以在页面上将此标记声明为任何移动Web窗体控件的子集。清单19-14是一个使用DeviceSpecific控件的示例。
清单19-14 DeviceSpecific和Choice
<mobile:DeviceSpecific ID="DeviceSpecific1" Runat="server">
<Choice Filter="isHTML32">
<HeaderTemplate >
<mobile:Label ID="Label1" Runat="server">Header Template - HTML32</mobile:Label>
<mobile:Command ID="Command1" Runat="server">Submit</mobile:Command>
</HeaderTemplate>
<FooterTemplate>
<mobile:Label ID="Label2" Runat="server">Footer Template</mobile:Label>
</FooterTemplate>
</Choice>
<Choice Filter="isPocketIE">
<HeaderTemplate>
<mobile:Label ID="Label1" Runat="server">Header Template - PocketIE</mobile:Label>
<mobile:Command ID="Command1" Runat="server">Submit</mobile:Command>
</HeaderTemplate>
<FooterTemplate>
<mobile:Label ID="Label2" Runat="server">Footer Template</mobile:Label>
</FooterTemplate>
</Choice>
</mobile:DeviceSpecific>