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

DataGrid3
DataGrid3 通过添加可视格式化和内容格式化构建于 DataGrid2 之上。
摘自 DataGrid3.aspx：
〈%@ Page language="C#" src="DataGrid.cs" inherits="Samples.Data
GridPage"%〉
...
〈asp:DataGrid runat=server id="titlesGrid"
AutoGenerateColumns="false"
Width="80%"
BackColor="White"
BorderWidth="1px" BorderStyle="Solid" CellPadding="2" Cell
Spacing="0"
BorderColor="Tan"
Font-Name="宋体" Font-Size="8pt"〉
〈property name="Columns"〉
〈asp:BoundColumn headerText="Title" DataField="title"/〉
〈asp:BoundColumn headerText="Author" DataField="au_name"/〉
〈asp:BoundColumn headerText="Date Published" DataField=
"pubdate"
DataFormatString="{0:MMM yyyy}"/〉
〈asp:BoundColumn headerText="Price" DataField="price"
DataFormatString="{0:c}"〉
〈property name="ItemStyle"〉
〈asp:TableItemStyle HorizontalAlign="Right"/〉
〈/property〉
〈/asp:BoundColumn〉
〈/property〉
〈property name="headerStyle"〉
〈asp:TableItemStyle BackColor="DarkRed" ForeColor="White"
Font-Bold="true"/〉
〈/property〉
〈property name="ItemStyle"〉
〈asp:TableItemStyle ForeColor="DarkSlateBlue"/〉
〈/property〉
〈property name="AlternatingItemStyle"〉
〈asp:TableItemStyle BackColor="Beige"/〉
〈/property〉
〈/asp:DataGrid〉
此.aspx 文件显示了与前面相同的 DataGrid 控件声明，并设置了各种
样式属性。这将导致视觉上更具吸引力的表示。仍就不需要对代码进行任
何更改，使用与以前示例相同的有代码支持的文件。
因为它是从 WebControl 得到的，所以 DataGrid 控件继承了诸如
Width、BackColor、BorderStyle 和 Font.Name 之类的样式属性。此外，
DataGrid 提供诸如 CellPadding 这样的属性，这些属性是特定于表的。这
些属性允许从总体上定制控件。
声明还显示了设置的若干项目样式，如 headerStyle 和 Alternating
ItemStyle。这些样式控制着它们相应项目的外观。请注意此示例中出现
的样式合并。备选项目与一般项目的前景色相同，因为它们的样式是
AlternatingItemStyle 和 ItemStyle 的组合。最后，此示例还通过右对齐
价格列中的文本说明了为特定列设置样式。
DataGrid 还允许您格式化其单元格中的文本内容。这是通过设置 Bound
Column 的 DataFormatString 属性值完成的。该列使用其格式说明格式化使
用 String.Format 的单元格内容。此属性可随格式化类型（如日期或货币）
一起预置或附加任意内容。此外，由于格式化考虑了当前页的 CultureInfo
和请求，所以它也支持全局化。如果未指定格式，则使用该值的 ToString
方法。
DataGrid4
DataGrid4 说明如何通过处理 SelectedIndexChanged 事件来利用
DataGrid 中的选择。
截自 DataGrid4.aspx：
〈%@ Page language="C#" src="DataGrid4.cs" inherits="Samples.
DataGrid4Page"%〉
...
〈asp:DataGrid runat=server id="titlesGrid"
AutoGenerateColumns="false"
Width="80%"
BackColor="White"
BorderWidth="1px" BorderStyle="Solid" CellPadding="2"
CellSpacing="0"
BorderColor="Tan"
Font-Name="宋体" Font-Size="8pt"
DataKeyField="title_id"
OnSelectedIndexChanged="OnSelectedIndexChangedTitlesGrid"〉
〈property name="Columns"〉
〈asp:ButtonColumn Text="Select" Command="Select"/〉
〈asp:BoundColumn headerText="Title" DataField="title"/〉
〈asp:BoundColumn headerText="Author" DataField="au_name"/〉
〈asp:BoundColumn headerText="Date Published" DataField=
"pubdate"
DataFormatString="{0:MMM yyyy}"/〉
〈asp:BoundColumn headerText="Price" DataField="price"
DataFormatString="{0:c}"〉
〈property name="ItemStyle"〉
〈asp:TableItemStyle HorizontalAlign="Right"/〉
〈/property〉
〈/asp:BoundColumn〉
〈/property〉
〈property name="headerStyle"〉
〈asp:TableItemStyle BackColor="DarkRed" ForeColor="White"
Font-Bold="true"/〉
〈/property〉
〈property name="ItemStyle"〉
〈asp:TableItemStyle ForeColor="DarkSlateBlue"/〉
〈/property〉
〈property name="AlternatingItemStyle"〉
〈asp:TableItemStyle BackColor="Beige"/〉
〈/property〉
〈property name="SelectedItemStyle"〉
〈asp:TableItemStyle BackColor="PaleGoldenRod" Font-Bold=
"true"/〉
〈/property〉
〈/asp:DataGrid〉
...
〈asp:Label runat=server id="selectionInfoLabel" Font-Name="宋体"
Font-Size="8pt"/〉
在此.aspx 文件中，为 DataGrid 的 SelectedIndexChanged 事件注册了
一个事件处理程序。此事件处理程序是在有代码支持的文件中实现的。已
在列集合中添加了一个命令为“Select”的 ButtonColumn，使得 DataGrid
为每个项目表示一个包含 Select 按钮的附加列。同时指定了 SelectedItem
Style。此样式用于从视觉上区分选定的项目。最后还指定了 DataGrid 的
DataKeyField 属性。此字段将置入 DataGrid 的 DataKeys 集合，该集合将在
有代码支持的文件中用到。
DataGrid4.cs：
namespace Samples {
...
public class DataGrid4Page : Page {
protected DataGrid titlesGrid;
protected Label selectionInfoLabel;
public ICollection GetTitlesList() {
// 从在应用程序状态中高速缓存的 DataSet 中检索标题列
表。
DataSet titlesDataSet = (DataSet)Application["Titles
DataSet"];
if (titlesDataSet != null) {
return titlesDataSet.Tables["Title"].DefaultView;
}
else {
return null;
}
}
private void LoadTitlesGrid() {
// 从数据库中检索数据
ICollection titlesList = GetTitlesList();
// 设置控件的数据源并重新设置其选择，
titlesGrid.DataSource = titlesList;
titlesGrid.SelectedIndex = -1;
// 并使该控件使用此数据源构建其项目
titlesGrid.DataBind();
// 更新选定的标题信息
UpdateSelectedTitleInfo();
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
if (!IsPostBack) {
// 首次请求此页
LoadTitlesGrid();
}
}
// 处理 DataGrid 的 OnSelectedIndexChanged 事件
protected void OnSelectedIndexChangedTitlesGrid(object
sender,
EventArgs
e) {
UpdateSelectedTitleInfo();
}
private void UpdateSelectedTitleInfo() {
// 获取选定的索引
int selIndex = titlesGrid.SelectedIndex;
string selTitleID = null;
string selectionInfo;
if (selIndex != -1) {
// 显示选定标题的关键字段
selTitleID = (string)titlesGrid.DataKeys[selIndex];
selectionInfo = "ID of selected title: " +
selTitleID;
}
else {
selectionInfo = "No title is currently selected.";
}
selectionInfoLabel.Text = selectionInfo;
}
}
}
此 .cs 文件包含处理 SelectedIndexChanged 事件以及在 DataGrid
下显示选定标题的 ID 的逻辑。DataGrid 处理命令事件，该事件是通过包含
在其项目中的按钮触发的。它识别标准命令“Select”，该命令使其更改
它的 SelectedIndex 属性，并通过触发此事件来将此更改通知用户的代码。
在实现事件处理程序的过程中，示例代码调用 UpdateSelectedTitle
Info 方法。该方法负责显示有关选定书名的信息，本例中为标题的 ID。
在更现实的方案中，此 ID 可用来链接某个页面，以显示有关选定标题的
更多详细信息。
ID 是通过访问 DataKeys 集合进行检索的。该集合是因为设置了
DataKeyField 属性而置入的。通常，将它设置为主关键字或使用户可以唯
一标识项目的某些其它字段，并将此信息用作后续的数据库查询或过滤数
据中的准则。
此示例说明除了仅仅表示数据源中的对象之外，如何进一步支持诸如
选择数据源中对象之类的操作。DataGrid 包含对若干其它特性（如排序、
分页、现场编辑和 TemplateColumns）的支持。但是，这些特定特性超出
了本文的讨论范围，将在以后的文章中加以探讨。
Repeater、DataList 或 DataGrid？
Repeater、DataList 和 DataGrid 控件共享公用编程模型。同时，每个
控件都被设计为侧重某个特定方案，为正确的方案选择正确的列表绑定控
件是一个重要的决策。本节说明控件层次结构和每种控件的功能，以及每
种控件可能用于的典型方案的示例。
正如在下面的类层次结构中看到的那样，Repeater 是一种小巧轻便的
控件。它只继承了基本 Control 类的功能，如 ID 属性和子控件集合。另
一方面，DataList 控件和 DataGrid 控件都继承了 WebControl 功能，
如样式和外观属性。
在对象模型方面，repeater 控件是最简单的控件。它同时也是最小的
数据绑定控件并且基本上是不同的，即它不会强制使用任何特殊的 UI 布局。
最后的表示遵循生成文本的方法，其方式是通过重复为此控件指定的模板
内容。此控件对样式和外观属性或行为不提供任何内建的支持。对于需要
完全控制表示的方案而言，它是一个极好的选择。
DataList 控件是强制使用分列布局或流布局的 repeater。它继承了
WebControl 中实现的外观属性，并增加了适用于它所创建的项目的其它
样式属性。DataList 控件还包括对其项目标准操作（如选择、编辑和删除）
的支持。它很适用于生成分布于一列或多列的水平或垂直的项目序列流。
DataGrid 控件强制使用列或行的列表布局。与 DataList 类似，此控件
提供样式和外观属性。除选择和编辑之外，DataGrid 还支持对整个项目集
合的高级操作，如分页和排序。DataGrid 和 DataList 的一个主要区别
是 DataGrid 不包含任何模板属性，即 DataGrid 控件的项目或行是非模
板化的。但是，将 TemplateColumn 添加到 DataGrid 中就可以在特定列
中使用模板。
下表是列表绑定控件所提供的功能的摘要。
功能 Repeater DataList DataGrid
模板 是（必需） 是（必需） 列内（可选）
列表布局 否 否 是
流布局 是 是 否
分列/报纸栏目样式布局 否 是 否
样式和外观属性 否 是 是
选择 否 是 是
编辑 否 是 是
删除 否 是 是
分页 否 否 是
排序 否 否 是
相关资源
随 Microsoft .NET Framework SDK 发布的 QuickStart 示例包含这些
控件的若干示例，以及说明使用 XML 和 Web 服务存取数据的示例。SDK
附带的文档包括相关主题的概念性资料，如 ASP+页面框架和服务器控件，
以及说明作为此框架一部分的控件的对象模型的参考书目。