asp.net|控件
概述
在很多情况下,我们都会使用到列表控件来方便用户选择一些选项。例如在某网站上注册新用户时,通常会询问你的性别是"男"还是"女",这时我们用单项按钮以供用户做出相应的选择。还有当你填写自己的家庭地址时,通常会使用到一个包含各省省名的下拉列表来供用户直接选择,这样可以减少用户的输入量。上述的这些单项按钮和下拉列表都在ASP.NET移动程序中都是以列表控件的形式存在的。我们可以使用列表控件来呈现各种形式(单项、多选、下拉列表)的列表,以供用户选择和使用。但是在ASP.NET 2.0移动开发工具包中,只有三个列表控件,分别为SelectionList 、List和ObjectList 控件。虽然没有ASP.NET 2.0中那么多类型的列表控件,但是我们却可以使用SelectionList 、List和ObjectList这三个列表控件实现单项、多选等几乎所有的功能。在本系列文章中将探讨这三个控件的一些基本功能和使用方法,并说明这三个控件相似之处及异同点。
图1是SelectionList 、List和ObjectList三个控件在类的继承上的关系:
图1
上面的三个列表控件中,SelectionList是最简单的,但是它可以以各种不同的类型进行呈现,因此具有很大的灵活度,以供不同的需求使用应用的列表类型。同时因为SelectionList控件不支持分页功能,所以在包含多个列表项的情况下,该控件就显得力不从心了。还有一点要需要重点说明的是,SelectionList是这三个列表控件中唯一支持多选的。而且该控件还可以以下拉列表的形式进行呈现,也可以以单项和多选框的方式进行呈现,当然这种呈现格式必须要被移动设备上的浏览器所接受。在一些WML浏览器上,只支持一些特殊的呈现形式,例如单项和多选按钮,并不支持下拉列表这种呈现形式。图2演示了下拉列表在不同浏览器上呈现时所存在的差别。
图2 在上图所示的PocketIE浏览器上,列表控件是以下拉列表的形式呈现的。而在Openwave的WML浏览器上,下拉列表类型的呈现形式是不支持的,为此在该浏览器中,是将列表中的各个列表项显示出来,供用户进行相应的选择。
List列表控件支持分页功能,这就意味着它支持列表项较多的列表。它只可以以项目符号列表或编号列表的形式进行呈现(只要浏览器支持即可)。除了之外,其它的被SelectionList支持的列表形式(例如下拉列表),在List中均无法实现。图3中List列表控件就是以编号列表的形式呈现的,并且支持分页功能。
图3 List列表控件以编号列表的形式呈现在页面上,而且支持分页功能。
在上述三个列表控件中最复杂的当属ObjectList 控件了。SelectionList和List控件允许你使用服务器控件语法静态地声明列表项,但是ObjectList控件是无法采用这种方式来添加列表项的,你必须在ObjectLis列表控件与相应的数据源绑定后,再通过代码将列表项添加到列表中。ObjectList 控件允许一个列表项中同时显示多个字段,这是其它两个控件所不具备的,它们只允许每个列表项只显示一个字段的信息。除此之外,ObjectList 控件中的每个列表项还可以和多个命令相关联,其它两个控件所不具备的功能。
图4 ObjectList 控件中,可以在每个列表项中显示多个字段。这里同时显示了球队名称、输、赢和积分等字段。
图5 每个列表项可以和多个命令进行关联,页面下方的各个链接就是与列表项关联的命令,你可以选择不同的命令,产生不同的操作
下表概括了上述三个控件的主要功能:
能力 | SelectionList | List | ObjectList |
是否可以以下拉列表、列表框、 单项或多选按钮等类型在HTML浏览器上进行呈现 | √ | ||
是否支持多选 | √ | ||
以项目符号列表或编号列表的形式进行呈现 | √ | ||
当列表包含较多的列表项时,是否可以启用分页功能 | √ | √ | |
是否可以通过服务器语法声明静态地生成列表项 | √ | √ | |
是否可以与数据源绑定 | √ | √ | √ |
在一个列表项中是否可以同时显示多个字段 | √ | ||
在选择一个列表项后是否会触发相应的事件 | √(注释) | √ | √ |
每个列表项是否可以自定义相关联的命令 | √ | ||
是否支持模板 | √ | √ | |
注释:SelectionList列表控件在选择一个列表项后,其自身是无法自动产生一个回发(postback)操作的。你必须在包含该SelectionList列表控件的Form控件上放置一个Command控件,再由该Command控件将因列表选项发生改变的信息回发到服务器上,这样ASP.NET运行时就可以根据这些信息做出相应的处理,并将处理后的信息返回到移动页面上。 |
采用不同的方式构建列表
在开始探究每个列表控件的具体用法时,我们首先来了解一下上述三个控件的共同特性。SelectionList和List控件允许开发人员定义静态地定义各个列表项,也就是我们可以在服务器控件语法中使用<Item>标签,来定义每个列表项对应的文本信息和值信息,而动态的实现方式就是通过代码,创建和列表中的每个列表项对应的System.Web.UI.MobileControls.MobileListItem 对象,并将这些对象添加到列表控件的Items集合中。由于每个列表项都是预先设置好的,所有我们也称这种列表为静态列表。
还有一种方式就是将列表控件与一个数据源进行绑定,由于该列表控件中的所有列表项所需的文本信息和值信息都读取自数据源,因此这些列表项都是根据这些信息动态生成。注意,上述的三个列表控件都支持数据绑定的方式动态地生成列表。
静态列表的实现
前文提过,我们可以通过静态的方式实现列表。其实这种实现就是在服务器控件语法中使用<Item>标签来设置每个列表项所需的文本信息和值信息。下面我们来通过一段代码来说明如何静态地实现一个列表。程序清单1是一个SelectionList控件的声明,我们希望通过该列表控件来选择一个列表项。在这里我们将手机的品牌和型号分别作为列表项的文本信息和值信息,你可以在每个<Item>标签中使用Text属性自动文本信息,使用Value属性指定值信息。
程序清单1:
<mobile:SelectionList id="SelectionList1" runat="server">
<Item Text="Dopoda" Value="P800" />
<Item Text="Motorola" Value="A1200" />
<Item Text="Nokia" Value="N70" />
<Item Text="Samsung" Value="E638" />
</mobile:SelectionList>
我们将在"SelectionList列表控件详解"这一章中通过具体的实例来应用程序清单1中的代码,在这只是简要地介绍下实现静态列表的方法。其实我们还可以以一种可视化的方式来实现静态列表,当然这要依靠Visual Studio 2005开发环境的支持。在Visual Studio 2005中,提供了一个非常有用的属性生成器,使得你可以很方便地定义一个静态列表。只要你选择列表控件的智能标签,而后再选择"属性生成器"链接,就会弹出"属性生成器"对话框。我们可以通过该对话框以可视化的方式产生程序清单1中的代码,如图6所示。
图6 我们可以在该对话框中通过"创建新项"按钮来产生一个新的列表项,而后在这个列表项对应的"项文本"和"值"文本框处填写好列表项的文本信息和值信息,就创建好了一个列表项。如果你要调整各个列表项之间的次序,可以点击上下箭头按钮来做出相应的调整。 在"属性生成器"对话框的"常规"选项卡中,用户可以选择列表控件在页面上的呈现形式。例如SelectionList列表控件支持下拉列表、列表框、单项按钮、复选按钮和多选列表框等几种形式,开发人员可以根据实际的需要选择合适的类型,如图7所示。
ASP.NET运行时是通过下面所描述的方式来解析服务器控件语法中的各个列表项的。在你使用静态的方式构建一个列表时,ASP.NET实际上是针对这个列表中的每个列表项,都创建一个System.Mobile.UI.MobileControls.MobileListItem对象,并使用<Item> 标签中的Text和Value属性指定的文本信息和值信息对相应的MobileListItem对象进行初始化,而后再将初始化后的MobileListItem对象添加到一个System.Mobile.UI.MobileControls.MobileListItemCollection集合对象中。我们可以在代码中通过SelectionList或List类的Items属性来访问这个MobileListItemCollection集合对象。事实上,程序清单1和程序清单2的功能是相同的,两种方式都可以生成静态列表,只不过程序清单1隐藏了静态列表的底层的实现,更容易操作罢了。
程序清单2
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SelectionList1.Items.Add(new MobileListItem("Dopoda", "P800"));
SelectionList1.Items.Add(new MobileListItem("Motorola", "A1200"));
SelectionList1.Items.Add(new MobileListItem("Nokia", "N70"));
SelectionList1.Items.Add(new MobileListItem("Samsung", "E638"));
}
}
将列表控件与数据集合进行绑定
前文提过,除了使用静态的方式定义列表外,我们还可以将SelectionList 、List和ObjectList三个列表控件与特定的数据源进行绑定。这些列表控件支持两种类型的数据源: System.Collections.IEnumerable和System.ComponentModel.IListSource。.Net Framework中的许多集合类都是实现了IEnumerator接口,为此这些类都支持简单的枚举功能。至于这些类的具体实例有位于System.Collections命名空间的Array、ArrayList、Hashtable和ListDictionary,还要一些和控件相关联的集合对象(例如前面的代码中使用到的MobileListItemCollection)。如果你要查看所有实现了IEnumerator接口的集合类的话,请自行参考MSDN帮助文档。
你还可以将列表控件与IListSource数据集合进行绑定。System.Data命名空间中的两个类实现了IListSource这种接口,这两个类就是我们在ADO.NET中经常使用的DataSet和DataTable。我们知道这两个类是相关联的,因为DataSet相当于一个由多个DataTable组成的集合。DataSet类是ADO.NET构架中的一个主要组件,并且DataSet还相当于在数据库中所检索到的数据在内存中的一个缓存。当列表控件的数据源为一个DataSet对象时,因为一个DataSet可能包含多个DataTable对象,所以我们还必须使用SelectionList.DataMember属性确切地指定使用那个DataTable对象来填充列表项。注意,当你使用一个IEnumerator数据源时,是没有必要指定DataMember属性的。至于DataSet在ASP.NET移动程序中的具体应用,将在其它章节中进行介绍。
当你需要以数据绑定的方式动态地实现一个列表的话,那么应该将该列表控件的DataSource属性指定一个相关联的数据源。如果数据源是一个DataSet对象的话,那么还需要使用DataMember属性确切地指定用那个DataTable填充列表项。对于SelectionList和List控件来说,你可以使用DataTextField和DataValueField两个属性分别指定数据源中的两个字段,列表控件会自动将这两个字段的内容作为各个列表项的文本信息和值信息。而ObjectList列表控件是使用LabelField属性来指定数据源中的一个字段,使得该字段中的内容应用到各个列表项中进行呈现,至于每个列表项的其它字段内容,你可以在ObjectList的详细信息视图页上进行查看。
我们可以以代码的方式或服务器控件语法的方式实现上述数据绑定属性的设置。例如,你希望在一个SelectionList列表控件中使用Manufacturer字段作为各列表项的文本信息,且Model字段作为各列表项的值信息。那么其设置的方法如程序清单3所示:
程序清单3
<mobile:SelectionList ID="SelectionList1" Runat="server" SelectType="MultiSelectListBox" DataTextField="Manufacturer" DataValueField="Model">
</mobile:SelectionList>
为了获取数据源中对应字段的内容,我们还需要定义一个类,使得每个列表项都可以读取相应的文本信息和值信息。
程序清单4
public class MobileTelephone
{
private String manufacturer, model;
public MobileTelephone(String manufacturer, String model)
{
this.manufacturer = manufacturer;
this.model = model;
}
public String Manufacturer { get { return this.manufacturer; } }
public String Model { get { return this.model; } }
}
然后,在Page_Load事件处理函数中,创建所有的数据项并将其添加到一个ArrayList对象中。最后就是设置列表控件的DataSource属性了,在这里我们将DataSource指定为这个ArrayList对象。完成上述的步骤再调用DataBind方法,这样就将列表控件和数据源进行绑定了。
程序清单4
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ArrayList array = new ArrayList();
array.Add(new MobileTelephone("Dopoda", "P800"));
array.Add(new MobileTelephone("Motorola", "A1200"));
array.Add(new MobileTelephone("Nokia", "N70"));
array.Add(new MobileTelephone("Samsung", "E638"));
SelectionList1.DataSource = array;
SelectionList1.DataBind();
}
}
使用上述代码的完整示例将在具体探讨每个列表控件时会应用到。
提示:DataBind方法对于数据绑定来说是至关重要的,很多开发人员经常忘记调用这个方法,以致列表控件不显示任何列表项。我们可以使用两种方法来使用DataBind方法,一种就是在每个要进行数据绑定的列表控件上单独使用DataBind方法,如程序清单4所示。你还可以采用一种一劳永逸的方法,那就是使用MobilePage.DataBind方法(在程序清单4中,使用this.DataBind()替代 SelectionList1.DataBind(),这里的this代表的就是MobilePage)。这样在页面上存在多个数据绑定的列表控件时,仅需使用一个this.DataBind()方法就可以实现所有列表控件和数据源的绑定,而无需为每个实现了数据绑定的列表控件都调用一次DataBind方法。