### 使用 ASP+ 列表绑定控件（上）

简介
Repeater、DataList 和 DataGrid 控件构成 ASP+页面框架中 System.Web.
UI.WebControls 名称空间内的相关 Web 控件集。这些控件使 HTML 显示所绑
定列表或数据源的内容。因此，将它们统称为“列表绑定控件”。
与框架中的其它 Web
控件类似，这些控件提供一致的编程模型并封装一个独立于浏览器的
表示逻辑。这些特性使开发人员能够针对对象模型编程而不用必须掌握与
HTML 相关的那些不一致的和复杂的技术知识。
这三种控件可以按多种布局（包括列表、分栏/报纸栏目和流布局
（HTML 流））来表示与其相关的数据源内容。此外，它们还允许您创建完
全不同的或完全定制的布局。除了封装有表示逻辑外，还提供了用来处理
已发送数据、执行状态管理和引发事件的功能。最后，它们还对诸如选择、
编辑、分页和排序之类的标准操作提供不同级别的支持。这些控件可以简
化几种常见的 Web 应用程序方案，包括报表、购物车、产品列表、查询
结果和导航菜单。
下面几节将进一步说明这些控件和如何在您的 Web 应用程序中使用
它们，以及如何选用控件。
列表绑定控件是如何工作的？
本节是本文其余部分的背景材料。概述了这些列表绑定控件的工作方
式、它们的共同特性以及某些相关概念。
DataSource 属性
每个控件都有一个 DataSource 属性，其类型为 System.Collections.
ICollection。用最简单的话来说，数据源是同类对象的一个列表或集合。
此框架中有几个对象提供了 ICollection 的实现。这个集合包括
System.Data.DataView（它通常用来访问关系数据库和 XML 数据）、一
般 ICollection 实现（如 ArrayList 和 Hashtable）以及数组。
与传统的数据绑定控件（它们通常需要 ADO 记录集）不同，除了实现
ICollection 接口之外，这些列表绑定控件未对其数据源强加任何其它要
求。根据设计，通过大量增加可作为有效 DataSource 属性值的类型和数据
结构，它们能够为您的应用程序代码实现最大程度的简单和灵活性。
项目集合
每个列表绑定控件都包含一个项目集合。控件通过列举这些对象当前
的数据源来置入其项目集合。在列举中为每个对象创建单个项目并用于表
示该对象。这些项目同时成为列表绑定控件中包含的控件层次结构的一部
分。
下表列出了与数据源的数据相关联的项目类型。
项目 创建的默认项目类型
AlternatingItem 为项目集合中具有奇数下标的项目创建
SelectedItem 为选定的项目创建（不论该项目是否为备选项目）
EditItem 为处于编辑模式下的项目创建（不管它是否被选中或是否为备选项目）
控件同时创建将在表示中用到的下列项目。但是，它们并不与数据源
的数据相关联。
标头 用来表示标头信息
注脚 用来表示注脚信息
分隔符 用来表示图 1 中所示的每个项目之间的内容，并且仅适用于 Repeater 和 DataList
分页符 用来表示与 DataGrid 控件相关联的分页 UI
项目的数据绑定和创建
列表绑定控件遵循在整个 ASP+ 框架中实现的显式数据绑定模型。这
意味着控件仅当其 DataBind 方法被调用时才需要并列举其数据源。
当调用 DataBind
方法时，列表控件将列举其数据源、创建项目并通过从其数据源中提
取值来对其进行初始化。如果启用了状态管理，则控件还将保存所需的全
部信息，以便在页面的回传处理期间重新创建其项目而无须重新设置数据
源。
显式数据绑定模型使您的应用程序代码可以精确地确定在处理序列中
何时及何处需要数据源。这种功能使对数据库服务器的访问更少且更高效，
而这些访问通常是 Web 应用程序最耗费资源的操作。
一般规则是每当您需要重新创建项目时都必须调用 DataBind。在大多
数情况下，您将在您的页面首次被请求创建初始项目集合时调用 DataBind。
在该页面的后续执行过程中，您将需要在引起项目集合被更改的各种事件
处理程序中调用此方法。当用于创建初始数据源的查询被修改时，就可能
发生这种情况。当项目的状态改变（如从只读模式变为编辑模式）时也可
能发生这种情况。
样式
通过在对象模型上使用样式属性，您可以定义全部 DataList 和 DataGrid
控件及其所包含项目的格式和外观。这些属性允许定制字体、颜色、边框
和其它外观因素。控件本身的样式属性（如前景色、背景色、字体和边框
样式）将影响整个控件的表示。
此外，每个控件都包含与其所创建的项目类型相匹配的大量样式属性，
如 as ItemStyle、AlternatingItemStyle 和 headerStyle。DataGrid 提供
第三级的样式属性，这些属性将影响特定列的所有单元格。控件中包含的
每一列都可以拥有其自己的 headerStyle、FooterStyle 和 ItemStyle。
模板
样式控制格式显示，而模板则定义每个项目的内容和表示。您可以将
模板看作 HTML 代码片断，它定义了用来表示项目的控件层次结构。
Repeater 和 DataList 控件由您指定的模板来驱动，提供各种可设
置的模板属性，如 ItemTemplate、AlternatingItemTemplate 和 header
Template。与样式类似，每个模板都对应于一个特定类型的项目。
DataGrid 控件未模板化。但是，控件的 Column 集合中的 Template
Columns 使 DataGrid 中模板的使用成为可能。TemplateColumn 中的每个单
元格都可以包含一个模板，这与 Repeater 或 DataList 控件中的项目极
为类似。这也使 DataGrid 中的定制表示成为可能。
模板中的数据绑定
模板定义项目中包含的控件层次结构。通过使用数据绑定表达式，此
层次结构中的控件属性可绑定到与此项目相关联的数据属性上。
作为模板的逻辑父级的项目在数据绑定表达式中被称为“容器”。每
个容器都有一个称为 DataItem 的属性，该属性引用其相关联的数据。结果
是，模板中的大多数典型数据绑定表达式都将控件属性绑定到 Container.
DataItem 的某个属性上。将在以下几节介绍的示例中进一步说明这种绑定。
Repeater 控件
如前面所述，Repeater 控件是完全由模板驱动的，允许创建完全可定
制的表示和布局。下图说明了这一功能。
摘自 Repeater1.aspx：
〈%@ Page language="C#" src="Repeater1.cs" inherits="Samples.
Repeater1Page"%〉
...
〈asp:Repeater runat=server id="linksListRepeater"
DataSource='〈%# SiteLinks %〉'〉
〈template name="headerTemplate"〉
〈ul type="1"〉
〈/template〉
〈template name="ItemTemplate"〉
〈li〉
〈asp:HyperLink runat=server
Text='〈%# DataBinder.Eval(Container.DataItem, "SiteName")
%〉'
NavigateUrl='〈%# DataBinder.Eval(Container.DataItem,
"SiteURL") %〉'〉
〈/asp:HyperLink〉
〈/li〉
〈/template〉
〈template name="FooterTemplate"〉
〈/ul〉
〈/template〉
〈/asp:Repeater〉
此.aspx 文件显示了一个用于生成带项目符号列表的 repeater 控件的
声明。
此示例说明了用数据绑定语法(〈%#...%〉)设置数据源的声明方法。
当您调用 DataBind 方法时，数据绑定中的表达式就会被执行。在这种情
况下，repeater 的 DataSource 属性被绑定到页面的 SiteLinks 属性上，
后者包含要显示的 URL 引用。
Repeater 是唯一允许在其模板中存在 HTML 片段的控件，将 Repeater
控件和 HTML 片段合在一起会产生良好形式的 HTML。在本示例中，带项目符
号的列表分为三个部分：
由 headerTemplate 表示的列表开始标记 (〈ul type="1"〉)。
由 FooterTemplate 表示的列表结束标记 (〈/ul〉)。
列表的主体由通过为 SiteLinks 集合中出现的每个对象重复 Item
Template 而生成的列表项 (〈li〉) 置入。
您也可以使用这些模板在标头中指定表的开始标记(〈TABLE〉)，在注
脚中指定表的结束标记(〈/TABLE〉)，在每个项目中指定单个表行(〈TR〉)。此替换选项将导致列表表示。
您必须指定 ItemTemplate。它是唯一必需的模板。当未指定其它模
板时，控件会自动将此 ItemTemplate 用于其它模板。
在以下示例中，ItemTemplate 包含一个 HyperLink Web 控件。此控
件的 Text 和 NavigateUrl 属性被绑定到与每个重复项目相关联的数据属性
上。这又是使用数据绑定表达式（在创建项目后立即对该表达式求值）完
成的。
Repeater1.cs:
namespace Samples {
...
public class Repeater1Page : Page {
protected Repeater linksListRepeater;
public ICollection SiteLinks {
get {
ArrayList sites = new ArrayList();
sites.Add(new SiteInfo("Microsoft Home",
"http://www.microsoft.com"));
sites.Add(new SiteInfo("MSDN Home",
"http://msdn.microsoft.com"));
sites.Add(new SiteInfo("MSN Homepage",
"http://www.msn.com"));
sites.Add(new SiteInfo("Hotmail",
"http://www.hotmail.com"));
return sites;
}
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
if (!IsPostBack) {
// 首次请求该页时即对其进行数据绑定 (DataBind)。
// 这将在此页的控件层次结构中递归调用每个控件。
DataBind();
}
}
}
public sealed class SiteInfo {
private string siteName;
private string siteURL;
public SiteInfo(string siteName, string siteURL) {
this.siteName = siteName;
this.siteURL = siteURL;
}
public string SiteName {
get { return siteName; }
}
public string SiteURL {
get { return siteURL; }
}
}
}
此 .cs 文件包含随前一个列表中的 aspx 页一起出现的代码。