电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

何时使用DataGrid、DataList 或Repeater


发布日期:2021/10/26
 

摘要了解 ASPNET 用于显示数据的三个控件 DataGridDataList 和 Repeater 这些控件中的每一个都有独特的特性以及相关的优点和缺点 创建显示数据的 ASPNET 应用程序时为这项工作选择正确的控件非常重要 正如将在本文中所看到的一样选择使用 DataGridDataList 还是 Repeater要权衡下面三个因素 可用性开发时间和性能 页打印页)

下载 DataControlsPerfTest_Setupmsi

本页内容

简介

数据 Web 控件之间的相似性

研究 DataGrid Web 控件

分析 DataList

深入研究 Repeater

小结

基准设置

简介

自从出现了像 Microsoft Active Server Pages (ASP) 这样的简单且基于脚本的 Web 编程技术以来Web 开发又有了很大的发展 传统 ASP 中常见的大量枯燥重复的编码工作在 Microsoft ASPNET 中不复存在了 例如正如所有传统 ASP 开发人员一度都知道的那样在传统 ASP Web 页面中显示数据需要下面的伪代码

Create connection to the databasePopulate an ADO Recordset with a SQL queryDisplay any header HTML neededFor Each Record in the Recordset Print out the Recordset field(s) and associated HTML Move to the next recordNextDisplay any footer HTML needed

例如要在 HTML <table> 中显示记录集的内容开发人员则不得不为 <table> 标记 (tag) 生成 HTML 标记 (markup)然后循环遍历记录集中的每一条记录每次循环生成一个 <tr> 标记以及许多 <td> 标记和要显示的记录集字段的值 最后在循环之后开发人员需要生成结束 <table> 标记

传统 ASP 所要求的这种方法有一个很大的缺点 它把 HTML 内容和 ASP Web 页面的源代码紧密集成在一起 因为没有分离代码和 HTML 内容所以更改 HTML 的内容及其困难尤其是对不懂编程技术的图形艺术家或 Web 设计者来说更是如此 而且因为检索数据库结果和生成它的内容都需要代码所以代码和 HTML 内容的这种集成相对来说需要大量的代码

幸好ASPNET 提供了三个控件使得在 ASPNET Web 页面中显示数据绝对比传统 ASP 所需的迭代方式简单得多 这三个控件是 DataGridDataList 和 Repeater以后我将称之为数据 Web 控件 也许如果您已经开发过 ASPNET Web 页面那么至少会对这三个控件中的一个有一些经验 通常开发人员从学习 DataGrid 开始这是因为 DataGrid 使用简单以及它具有允许数据排序分页和编辑的功能 但是在 ASPNET Web 页面中显示数据时DataGrid 并不总是控件的最佳选择

在本文中我们将研究这些数据 Web 控件中每个控件的独特特性 这些特性赋予每个数据 Web 控件许多优点和缺点 因为每一个数据 Web 控件都有一些缺点所以没有可用于任何作业的完美控件 决定使用哪个控件时必须权衡这三个数据 Web 控件每一个的优点和缺点然后再决定哪个控件是最合适的

为了协助进行比较研究每一个数据 Web 控件时我们将着重于这三个衡量标准 可用性(从 Web 访问者的角度)开发时间和性能 我们首先快速浏览一下这三个数据 Web 控件之间的相似性 接下来我们将深入研究 DataGrid然后研究 DataList最后查看 Repeater 对于每一个控件我们将研究这些控件的功能并讨论它的功能集是如何影响这些衡量标准的

返回页首

数据 Web 控件之间的相似性

在研究数据 Web 控件之间的差异(这些差异使它们区别于其他控件)之前先看一下它们的相似性 从较高级别观点来看最基本的相似性是DataGridDataList 和 Repeater都设计为了执行大致相同的操作 显示数据 另一个相似性把数据绑定到数据 Web 控件所需的代码 具体地说只需要下面两行代码

dataWebControlIDDataSource = someDataSourcedataWebControlIDDataBind()

通常赋给数据 Web 控件的 DataSource 属性的 someDataSource 对象是一个 DataSetSqlDataReaderOleDbDataReader 或一个集合(如 ArrayArrayList 或 SystemCollections 命名空间中的其他某个类) 但是任何实现 IEnumerable 接口的对象都可以绑定到数据 Web 控件

DataBind() 方法枚举指定的 DataSource 中的记录 对于 DataSource 中的每一条记录都会创建一个项并追加到数据 Web 控件的 Items 集合中 数据 Web 控件中的每一项都是一个类实例 用于控件每一项的特定类取决于该数据 Web 控件 例如DataGrid 中的每一项都是 DataGridItem 类的一个实例而 Repeater 中的每一项都是 RepeaterItem 类的一个实例

每个数据 Web 控件会为它的每一项使用不同的类因为是这些项呈现的方式决定了数据 Web 控件生成的 HTML 标记 例如DataGridItem 类是从 TableRow 类中派生的这意味着每个 DataGridItem 都或多或少地呈现为一个表行 这很有意义因为 DataGrid 设计为在 HTML <table> 标记内以表格形式显示数据在 HTML <table> 中每一项都呈现为单独一行 另一方面Repeater 设计为允许对它的输出进行完全自定义 因此RepeaterItem 类不从 TableRow 类中派生并不令人惊讶

数据 Web 控件之间的另一个相似性是每个控件都能使用模板提供高度自定义的输出 DataList 和 Repeater 控件必须 使用模板指定它们的内容而 DataGrid 则通过 TemplateColumn 列类型可以为特定的列选择使用模板(我们将在下一节研究 DataGrid Web 控件中讨论各种不同的 DataGrid 列类型)

最后一个值得注意的是 DataGrid 和 DataList 控件是从 WebControl 类中派生的而 Repeater 控件是从 Control 类中派生的 WebControl 类包含许多美学方面的属性例如 BackColorForeColorCssClassBorderStyle 等 这意味着如果使用 DataGrid 和 DataList就可以通过它们从 WebControl 类中继承的属性指定样式设置 而 Repeater 没有任何这样的样式属性 正如我们将在深入研究 Repeater一节中所讨论的一样对 Repeater 输出的任何可视设置都必须在 Repeater 的模板中指定

返回页首

研究 DataGrid Web 控件

DataGrid Web 控件是这三个数据 Web 控件中功能最多的但是在自定义控件生成的实际 HTML 标记时它又是最不灵活的 呈现的 HTML 标记中的这种不灵活性是由于 DataGrid 是设计用于使用 HTML <table> 以表格形式显示数据所造成的 因此对于每一条绑定到 DataGrid 的记录都会创建一个单独的表行(<tr>)对于要显示的记录中的每一个字段都会创建一个单独的表列(<td>)

DataGrid 提供了许多功能可极大地提高要显示的数据的可用性 例如把 DataGrid 的 AllowSorting 属性设置为 True 并添加一点源代码开发人员就可以把一个普通的 DataGrid 变成一个其数据可以由最终用户排序的 DataGrid 另外再增加一点工作量开发人员就能增强 DataGrid 的功能以允许数据分页或数据的内联编辑 这些功能明显增强了 DataGrid 的可用性

除了在可用性方面得分很高DataGrid 还提供了很短的开发时间 要使用 DataGrid 开始在 ASPNET Web 页面中显示数据只需要把 DataGrid 添加到 Web 页面中并编写两行必要的代码 第一行把数据绑定到 DataGrid 的 DataSource第二行调用 DataGrid 的 DataBind() 方法 显然随着添加到 DataGrid 中的功能数量的增加开发时间也增加了但这只是把开发时间和其他数据 Web 控件进行比较 假设您要允许对 Repeater 显示的数据进行排序 添加这样的功能是一定可能的但是与用 DataGrid 完成同样的操作相比这需要明显多很多的时间和精力

尽管 DataGrid 具有良好的可用性和开发时间得分但是这个控件有两个固有的缺点 第一正如前面所谈到的DataGrid 在对所呈现的 HTML 标记进行自定义方面的功能很有限 是的您可以自定义 DataGrid 的不同行和列的字体颜色和边框但是事实仍然是当 DataGrid 显示数据时结果将是一个 HTML <table>DataSource 中的每一条记录都对应其中一个 <tr>每一个字段都对应其中一个 <td>

具体地说DataGrid 中的每一列都是一个从 DataGridColumn 类中派生的类实例 有五个内置的 DataGrid 列类型

BoundColumn

ButtonColumn

EditColumn

HyperLinkColumn

TemplateColumn

每一个列类型都提供数据或提供某种允许用户和 DataGrid 进行交互的接口 例如BoundColumn 以纯文本显示 DataSource 字段的值而 HyperLinkColumn 则会显示一个超级链接其文字和 URL 部分可能是 DataSource 字段 除了这些内置的列类型通过创建 DataGridColumn 类的派生类还可以创建自定义 DataGrid 列类型 (有关创建一个用于扩展 BoundColumn 功能以限制显示字符数的列的示例请参阅 Creating a Custom DataGridColumn Class

有了这么多的 DataGrid 列类型可能就不理解为什么 DataGrid 呈现的 HTML 标记不能进行高度自定义了 要知道虽然每一个 DataGrid 列类型在呈现时生成不同的 HTML但是每一列都包含在一组 <td> 标记中每一行都包含在一组 <tr> 标记中 因此即使可以用 TemplateColumn 自定义每一行的特定列的 HTML 输出而 DataGrid 仍然呈现为 HTML <table>其中每一行使用一个 <tr>每一列使用一个 <td> DataGrid 的这种限制禁止了更多具有创造性的数据显示 例如如果要在每一表行中显示五条记录就不能使用 DataGrid必须使用DataList 或 Repeater 另外如果要在除 <table> 之外的 HTML 标记中显示数据很遗憾就不能使用 DataGrid 了

DataGrid 第二个缺点是它的性能 DataGrid 是这三个数据 Web 控件中性能最差的 基于这一点由 DataGrid - 特别是具有许多行的 DataGrids - 产生的 ViewState 可能会非常大 如果使用 DataGrid 仅仅是为了显示数据则可以关闭 ViewState但是使用 DataGrid 的排序分页或编辑功能时就不能这样做了

为了测试 DataGrid 的性能我使用了 Microsoft 的免费 Web Application Stress Tool (WAST) 在本文最后的基准设置一节中列出了精确的测试条件和 WAST 设置 另外测试使用的代码也可在本文最后下载

这个 Web Application Stress Tool 会向 Web 服务器发出一组特定的 URL 请求 对于每一项测试我都在一分钟之内尽可能快地不断请求一个 URL WAST 报告了许多性能衡量标准我要关注的一个衡量标准是每秒请求数它表明了 Web 服务器每秒能执行多少次 ASPNET Web 页面

对于一个仅显示数据的简单 DataGrid运行了两个测试 具体地说DataGrid 显示了来自 Northwinds 数据库的 Customers 表(Customers 表总共包含 条记录)的四个字段 DataGrid 的 AutoGenerateColumns 属性设置为 True 第一项测试把 DataGrid 放在一个 Web 窗体( <form runat=server>)中而第二项测试则没有 如果在窗体中放置一个控件而不把它的 EnableViewState 属性显式设置为 False那么该控件则会用 ViewState 保持它的状态 创建这个 ViewState 项可能是一个比较费时的过程因此减少了可处理的总的每秒请求数结果如图 所示

正如我们将要在研究 DataList 和 Repeater 时看到的一样这两个控件都提供了比 DataGrid 更好的性能

返回页首

分析 DataList

记得 DataGrid 将呈现为 HTML <table>每一个 DataSource 记录作为一个表行(<tr>)每一个记录字段作为一个表列(<td>) 有时您可能想更多地控制数据的显示 例如您可能想把数据显示在 HTML <table> 中但不是每行显示一条记录而是每行显示五条记录 或者您根本不想把数据显示在 <table> 标记中而是想把每个元素显示在一个 <span> 标记中DataList 放弃了 DataGrid 所采用的概念 相反DataList 的显示是通过模板 定义的 利用模板开发人员可以指定混合的 HTML 语法和数据绑定语法 HTML 语法是标准的 HTML 标记数据绑定语法是使用 <%# 和 %> 标记分隔的用于从 DataSource 的记录中产生用于构造给定 DataList 项的内容 例如下面的 ItemTemplate 将显示 DataSource 的字段 CompanyName

<asp:DataList runat=server id=myDataList> <ItemTemplate> <%# DataBinderEval(ContainerDataItem CompanyName) %> </ItemTemplate></asp:DataList>

除了数据绑定语法模板也可以包含 HTML 标记 通过更新上面的模板可以使 CompanyName 字段以粗体显示而使 ContactName 字段以非粗体显示在 CompanyName 字段的下面

<asp:DataList runat=server id=myDataList> <ItemTemplate> <b><%# DataBinderEval(ContainerDataItem CompanyName) %></b> <br /> <%# DataBinderEval(ContainerDataItem ContactName) %> </ItemTemplate></asp:DataList>

对于 DataList 的 DataSource 中的每一条记录都要计算 ItemTemplate 的数据绑定语法 数据绑定语法的输出与 HTML 标记一起指定了为 DataList 项呈现的 HTML DataList 还支持其他六个模板包括 ItemTemplate在内共有如下七个 AlternatingItemTemplate

EditItemTemplate

FooterTemplate

HeaderTemplate

ItemTemplate

SelectedItemTemplate

SeparatorTemplate

注意DataGrid 的 TemplateColumn 仅支持四个模板 ItemTemplateHeaderTemplateFooterTemplate 和 EditItemTemplate默认情况下DataList 将每一项都显示为 HTML <table> 中的一行 但是通过设置 RepeatColumns 属性您可以指定表的每一行显示多少个 DataList 项 除了可以指定 HTML <table> 的每一行显示多少个 DataList 项之外还可以指定 DataList 的内容应该使用 <span> 标记显示而不是使用 <table> 标记 DataList 的 RepeatLayout 属性可以设置为 Table 或 Flow表示 DataList 中的数据呈现在 HTML <table> 中还是 <span> 标记中利用模板以及 RepeatColumns 和 RepeatLayout 属性很明显 DataList 比 DataGrid 允许对呈现的 HTML 标记进行更多的自定义 这种增强了的自定义使得使用 DataList 能够产生更为友好的数据显示因为 DataGrid 的每一条 DataSource 记录占用一个表行的单 HTML <table>模型不可能总是用于显示信息的最佳选择 但是只研究比 DataGrid 改进了的自定义并不足以确定 DataList 的可用性我们还必须比较 DataGrid 和 DataList 的排序分页和编辑功能 使用 EditItemIndex 模板以及 EditCommandUpdateCommand 和 CancelCommand 事件DataList 可以支持内联编辑 但是用 DataList 添加这样的功能比用 DataGrid 花费的开发时间要长 开发时间的差异是由于下面两个原因 通过 EditCommandColumn 列类型即可在 DataGrid 中创建的编辑/更新/取消按钮必须手动添加到 DataList 中以及DataGrid BoundColumn 列类型自动使用 TextBox Web 控件作为编辑接口而使用 DataList 时必须通过 EditItemTemplate 为要编辑的项显式指定的编辑接口

虽然用 DataList 进行内联编辑不是很困难但是 DataList 的数据排序分页和编辑却很困难 虽然一些灵活的编码肯定能完成这样的功能但是向 DataList 中添加这样的功能将花费相当多的开发时间 因此如果最终用户能对数据进行排序和分页是一个必需要求的话那么最好选择 DataGrid 而不选择 DataListDataList 的性能比 DataGrid 的性能好当 DataList 位于 Web 窗体内时这一点更明显 显示了 Web Application Stress Tool 在 DataList 上的测试结果

DataList 的每秒请求数

正如图 中的结果显示的那样当 DataList 放置在 Web 窗体内时(因此导致该 Web 控件生成它的 ViewState)该 Web 控件要远胜于 DataGrid

返回页首

深入研究 Repeater

在所有这三个数据 Web 控件中Repeater Web 控件在呈现的 HTML 里提供了最大的灵活性 DataGrid 或 DataList 会在预设的 HTML 标记中自动包含开发人员指定的内容与它们不同的是Repeater 在呈现的时候将严格生成指定的 HTML 标记 因此如果不想用 HTML <table>或者一系列 <span> 标记显示数据而希望以其他方式显示数据就必须使用 Repeater 控件 就像 DataList 一样使用 Repeater 时要用模板指定标记 Repeater 包含下列五个模板 AlternatingItemTemplate

FooterTemplate

HeaderTemplate

ItemTemplate

SeparatorTemplate

HeaderTemplate 和 FooterTemplate 指定出现在绑定到 Repeater 的数据之前和之后的 HTML 标记 AlternatingItemTemplate 和 ItemTemplate 指定用于呈现 Repeater 的 DataSource 中的每条记录的 HTML 标记和数据绑定语法 例如假设您要把包含雇员信息的数据集绑定到 Repeater该数据集的其中一个字段是 EmployeeName 如果要在 Web 页上以无序列表的形式显示雇员列表则可以使用如下 Repeater 语法

<asp:Repeater runat=server id=rptEmployees> <HeaderTemplate> <ul> </HeaderTemplate> <ItemTemplate> <li><%# DataBinderEval(ContainerDataItem EmployeeName) %></li> </ItemTemplate> <FooterTemplate> </ul> </FooterTemplate></asp:Repeater>

与 DataGrid 和 DataList 不同Repeater 类不是从 WebControl 类派生的 因此Repeater 缺少 DataGrid 和 DataList 二者共有的样式属性 这一点归结起来无非是说如果想对 Repeater 中所显示数据进行格式设置则必须在 HTML 标记中进行这样的操作 例如在上面的例子中如果想用粗体显示雇员的姓名则必须更改 ItemTemplate 以包含 HTML 粗体标记就像下面这样

<ItemTemplate> <li><b><%# DataBinderEval(ContainerDataItem EmployeeName) %></b></li></ItemTemplate>

然而对于 DataGrid 或 DataList通过把控件的 ItemStyleFontBold 属性设置为 True就能用粗体显示文本了Repeater 缺少样式属性会大大增加开发的时间指标 例如假设决定使用 Repeater 显示数据这些数据需要以粗体中间对齐且带有特定背景色的特定字体显示 所有这些都要用几个 HTML 标记指定这些标记很快就会使 Repeater 的模板变得凌乱不堪 这种凌乱会使以后对外观进行更改变得困难得多尤其是当其他人对该项目进行操作时则不得不查看大量 HTML 语法 将这一点与为 DataGrid 或 DataList 指定格式进行比较 对于这两个控件中的任何一个都可以通过指定 DataGrid 或 DataList 的样式属性来使模板免于凌乱 此外可以用一些工具来自动设置 DataGrid 和 DataList 的样式属性例如 Microsoft Visual Studio NET 或 ASPNET Web Matrix除了延长开发时间之外Repeater 还缺少有助于支持分页编辑或数据编辑的内置功能 由于缺少这些功能支持Repeater 在可用性的评定中得分很低 当然如果 所有您感兴趣的只是显示数据而不用带任何别致的铃声或口哨声那么 Repeater 的功能匮乏就不是主要缺点了 我之所以强调如果一词是因为通常Web 应用程序一旦进行了部署用户就会发现他们需要附加的功能例如排序分页和编辑Repeater 有一个弥补性的品质(这并不令人吃惊)那就是性能 Repeater 的性能比 DataList 的性能稍微好一点比 DataGrid 的性能要好很多 显示了Repeater 每秒能处理的请求数并与 DataGrid 和 DataList 进行了对比

: Repeater 的每秒请求数

返回页首

小结

在 ASPNET Web 页面中显示数据时很多开发人员都选择他们最熟悉的数据 Web 控件通常是 DataGrid 但是这样的盲目决定不够明智因为根本没有通用的最好的数据 Web 控件 决定为给定的 Web 页使用哪个数据 Web 控件时应该先就以下各种问题自己考虑一下以确定哪个控件最适合手边的任务 您想允许用户对数据进行排序吗? 需要把数据用非 HTML <table> 的格式显示吗? 页面会被大量访问吗因而性能是一个关键的问题吗?因为 DataGrid 能允许最终用户排序分页和编辑它的数据所以这三个数据 Web 控件中 DataGrid Web 控件提供了最好的功能集 因为使用 DataGrid 时只需要把它添加到 Web 页面中并写几行代码所以 DataGrid 也是最简单易用的数据 Web 控件 但是容易使用和强大的功能是要付出代价的如性能的代价 DataGrid 是三个数据 Web 控件中效率最低的特别是当把它放置在 Web 窗体中时通过使用模板DataList 对显示的数据外观提供了比 DataGrid 更多的控制 但是使用模板通常比使用 DataGrid 的列类型需要更多的开发时间 DataList 还支持数据的内联编辑但是实现起来需要的工作量比 DataGrid 多 遗憾的是在 DataList 中提供分页和排序支持不是一件简单的事 DataList 比 DataGrid 提供了更好的性能从而弥补了这些缺少的内置功能最后Repeater 控件允许对呈现的 HTML 标记进行完整和全面的控制 对于 Repeater生成的唯一 HTML 是模板中数据绑定语句的值和模板中指定的 HTML 标记而不会生成象 DataGrid 和 DataList 那样的额外HTML 由于要求开发人员指定完整生成的 HTML 标记所以通常 Repeater 需要的开发时间最长 而且Repeater 不提供内置编辑排序或分页支持 但是Repeater 的性能确实是这三个数据 Web 控件中最好的 它的性能可与 DataList 相比但明显比 DataGrid 好祝大家编程愉快!

上一篇:学习反射中的动态创建对象

下一篇:使用Response.Redirect打开新窗口的方法