首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

决议何时使用 DataGrid、DataList 或 Repeater

2012-12-24 
决定何时使用 DataGrid、DataList 或 Repeater本页内容?简介??数据?Web?控件之间的相似性??研究?DataGrid?W

决定何时使用 DataGrid、DataList 或 Repeater

本页内容
?简介?
?数据?Web?控件之间的相似性?
?研究?DataGrid?Web?控件?
?分析?DataList?
?深入研究?Repeater?
?小结?
?基准设置?

简介
自从出现了像?Microsoft?Active?Server?Pages?(ASP)?这样的简单且基于脚本的?Web?编程技术以来,Web?开发又有了很大的发展。?传统?ASP?中常见的大量枯燥、重复的编码工作,在?Microsoft?ASP.NET?中不复存在了。?例如,正如所有传统?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?内容的这种集成相对来说需要大量的代码。

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

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

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

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

dataWebControlID.DataSource?=?someDataSourcedataWebControlID.DataBind()
通常,赋给数据?Web?控件的?DataSource?属性的?someDataSource?对象是一个?DataSet、SqlDataReader、OleDbDataReader?或一个集合(如?Array、ArrayList?或?System.Collections?命名空间中的其他某个类)。?但是,任何实现?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?类包含许多美学方面的属性,例如?BackColor、ForeColor、CssClass、BorderStyle?等。?这意味着如果使用?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?开始在?ASP.NET?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?服务器每秒能执行多少次?ASP.NET?Web?页面。

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


正如我们将要在研究?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>????<%#?DataBinder.Eval(Container.DataItem,?"CompanyName")?%>??</ItemTemplate></asp:DataList>
除了数据绑定语法,模板也可以包含?HTML?标记。?通过更新上面的模板,可以使?CompanyName?字段以粗体显示,而使?ContactName?字段以非粗体显示在?CompanyName?字段的下面:
<asp:DataList?runat="server"?id="myDataList">??<ItemTemplate>????<b><%#?DataBinder.Eval(Container.DataItem,?"CompanyName")?%></b>????<br?/>????<%#?DataBinder.Eval(Container.DataItem,?"ContactName")?%>??</ItemTemplate></asp:DataList>
对于?DataList?的?DataSource?中的每一条记录,都要计算?ItemTemplate?的数据绑定语法。?数据绑定语法的输出与?HTML?标记一起指定了为?DataList?项呈现的?HTML。?DataList?还支持其他六个模板,包括?ItemTemplate在内共有如下七个:???AlternatingItemTemplate?
??EditItemTemplate?
??FooterTemplate?
??HeaderTemplate?
??ItemTemplate?
??SelectedItemTemplate?
??SeparatorTemplate?
注意,DataGrid?的?TemplateColumn?仅支持四个模板:?ItemTemplate、HeaderTemplate、FooterTemplate?和?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?模板以及?EditCommand、UpdateCommand?和?CancelCommand?事件,DataList?可以支持内联编辑。?但是,用?DataList?添加这样的功能比用?DataGrid?花费的开发时间要长。?开发时间的差异是由于下面两个原因:???通过?EditCommandColumn?列类型即可在?DataGrid?中创建的编辑/更新/取消按钮,必须手动添加到?DataList?中,以及?
??DataGrid?BoundColumn?列类型自动使用?TextBox?Web?控件作为编辑接口,而使用?DataList?时必须通过?EditItemTemplate?为要编辑的项显式指定的编辑接口。?
虽然用?DataList?进行内联编辑不是很困难,但是?DataList?的数据排序、分页和编辑却很困难。?虽然一些灵活的编码肯定能完成这样的功能,但是向?DataList?中添加这样的功能将花费相当多的开发时间。?因此,如果最终用户能对数据进行排序和分页是一个必需要求的话,那么最好选择?DataGrid?而不选择?DataList。DataList?的性能比?DataGrid?的性能好,当?DataList?位于?Web?窗体内时这一点更明显。?图?2?显示了?Web?Application?Stress?Tool?在?DataList?上的测试结果。
图?2:?DataList?的每秒请求数
正如图?2?中的结果显示的那样,当?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><%#?DataBinder.Eval(Container.DataItem,?"EmployeeName")?%></li>??</ItemTemplate>??<FooterTemplate>????</ul>??</FooterTemplate></asp:Repeater>
与?DataGrid?和?DataList?不同,Repeater?类不是从?WebControl?类派生的。?因此,Repeater?缺少?DataGrid?和?DataList?二者共有的样式属性。?这一点归结起来无非是说,如果想对?Repeater?中所显示数据进行格式设置,则必须在?HTML?标记中进行这样的操作。?例如,在上面的例子中,如果想用粗体显示雇员的姓名,则必须更改?ItemTemplate?以包含?HTML?粗体标记,就像下面这样:
<ItemTemplate>??<li><b><%#?DataBinder.Eval(Container.DataItem,?"EmployeeName")????%></b></li></ItemTemplate>
然而对于?DataGrid?或?DataList,通过把控件的?ItemStyle-Font-Bold?属性设置为?True,就能用粗体显示文本了。Repeater?缺少样式属性会大大增加开发的时间指标。?例如,假设决定使用?Repeater?显示数据,这些数据需要以粗体、中间对齐且带有特定背景色的特定字体显示。?所有这些都要用几个?HTML?标记指定,这些标记很快就会使?Repeater?的模板变得凌乱不堪。?这种凌乱会使以后对外观进行更改变得困难得多,尤其是当其他人对该项目进行操作时,则不得不查看大量?HTML?语法。?将这一点与为?DataGrid?或?DataList?指定格式进行比较。?对于这两个控件中的任何一个,都可以通过指定?DataGrid?或?DataList?的样式属性来使模板免于凌乱。?此外,可以用一些工具来自动设置?DataGrid?和?DataList?的样式属性,例如?Microsoft?Visual?Studio?.NET?或?ASP.NET?Web?Matrix。除了延长开发时间之外,Repeater?还缺少有助于支持分页、编辑或数据编辑的内置功能。?由于缺少这些功能支持,Repeater?在可用性的评定中得分很低。?当然,如果?所有您感兴趣的只是显示数据,而不用带任何别致的铃声或口哨声,那么?Repeater?的功能匮乏就不是主要缺点了。?我之所以强调“如果”一词是因为,通常,Web?应用程序一旦进行了部署,用户就会发现他们需要附加的功能,例如排序、分页和编辑。Repeater?有一个弥补性的品质(这并不令人吃惊),那就是性能。?Repeater?的性能比?DataList?的性能稍微好一点,比?DataGrid?的性能要好很多。图?3?显示了Repeater?每秒能处理的请求数,并与?DataGrid?和?DataList?进行了对比。
图?3:?Repeater?的每秒请求数
返回页首
小结
在?ASP.NET?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?好。祝大家编程愉快!

热点排行