欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

程序员文章站 2023-12-13 20:40:46
导言   在之前的28篇教程的例子里,如果我们需要显示某个数据源的多条记录,我们使用gridview .gridview 的一行表示数据源的一条记录,列表示一个字段.虽然...

导言

  在之前的28篇教程的例子里,如果我们需要显示某个数据源的多条记录,我们使用gridview .gridview 的一行表示数据源的一条记录,列表示一个字段.虽然gridview 用来显示数据,分页,排序,编辑,删除非常的方便,但是有点臃肿.而且gridview 结构的标记是固定的—它包含一个带有<tr>和<td>的html <table>标记.

  为了在显示多条记录时,有更好的自定义功能,asp.net 2.0提供了datalist 和repeater (asp.net 1.x版本里也有 ).datalist 和repeater 使用模板来显示内容,而不是象在gridview里那样使用boundfields, checkboxfields, buttonfields等.datalist 的标记语言为html <table>, 不过它允许每一行显示多条记录.另一方面,repeater不会生成多余的标记语言,因此如果你想精确控制标记语言的生成,它是最理想的选择.

  在后面的若干章教程里,我们将从使用datalist 和repeater 的模板显示数据开始,来学习它们的最基本的用法.我们将学习如何控制这些控件的格式,如何在datalist里改变数据的布局,最常见的主/从场景,编辑和删除数据的方法,以及如何分页等.

第一步 1: 添加datalist 和repeater 教程页

  在开始本篇教程前,我们首先花点时间来创建一些页,这些页会在本篇和后面的几篇教程里用到.先添加一个名为datalistrepeaterbasics的文件夹,然后,添加下面的页,添加页的时候确保每页都选择了 site.master作为母板页:

default.aspx
basics.aspx
formatting.aspx
repeatcolumnanddirection.aspx
nestedcontrols.aspx

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 1: 创建 datalistrepeaterbasics 文件夹 和添加页

  打开default.aspx页的设计视图,从usercontrols文件夹将sectionleveltutoriallisting.ascx用户控件拖进来.这个用户控件提供的功能就是列出教程章节.我们在母板页和站点导航里创建的它.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 2: 添加sectionleveltutoriallisting.ascx 用户控件到default.aspx

最后,将这些页的地址加到 web.sitemap 的条目里.在paging and sorting <sitemapnode>之后添加下面的标记.

<sitemapnode
 title="displaying data with the datalist and repeater"
 description="samples of reports that use the datalist and repeater controls"
 url="~/datalistrepeaterbasics/default.aspx" >
 <sitemapnode
 title="basic examples"
 description="examines the basics for displaying data using the
   datalist and repeater controls."
 url="~/datalistrepeaterbasics/basics.aspx" />
 <sitemapnode
 title="formatting"
 description="learn how to format the datalist and the web controls within
   the datalist and repeater's templates."
 url="~/datalistrepeaterbasics/formatting.aspx" />
 <sitemapnode
 title="adjusting the datalist s layout"
 description="illustrates how to alter the datalist's layout, showing
   multiple data source records per table row."
 url="~/datalistrepeaterbasics/repeatcolumnanddirection.aspx" />
 <sitemapnode
 title="nesting a repeater within a datalist"
 description="learn how to nest a repeater within the template of a datalist."
 url="~/datalistrepeaterbasics/nestedcontrols.aspx" />
</sitemapnode>

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 3: 向 site map 里添加新的页

第二步: 在 datalist里显示product信息

  和formview一样,datalist 使用模板来显示信息,而非boundfields, checkboxfields等.而与formview不同的是,datalist 是被用来显示一组记录,而不是单独的一条.现在我们开始本章的教程.首先看看如何将product 绑定到datalist.打开datalistrepeaterbasics 文件夹里的basics.aspx 页,然后从工具箱里拖一个datalist 进来.如图4所示,在指定模板前,设计器会是灰色的.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 4: 从工具箱拖一个datalist到设计器里

  打开datalist的智能标签,添加一个objectdatasource ,使用productsbll 类的getproducts 方法来配置它.因为在本教程里创建的datalist 为只读的,因此在insert, update, 和delete 标签的下拉列表里都选择none.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 5: 创建一个新的objectdatasource

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 6: 用productsbll 类来配置objectdatasource

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 7: 使用getproducts 方法来获取所有product的信息

  通过智能标签里配置完objectdatasource ,并把它和datalist 关联起来后,visual studio会在datalist 里自动为数据源返回的每个字段创建一个itemtemplate 用来显示name 和value (见下面的代码).这个默认的itemtemplate看起来和绑定formview 时自动产生的模板是一样的.

<asp:datalist id="datalist1" runat="server" datakeyfield="productid"
 datasourceid="objectdatasource1" enableviewstate="false">
 <itemtemplate>
 productid: <asp:label id="productidlabel" runat="server"
    text='<%# eval("productid") %>' /><br />
 productname: <asp:label id="productnamelabel" runat="server"
    text='<%# eval("productname") %>' /><br />
 supplierid: <asp:label id="supplieridlabel" runat="server"
    text='<%# eval("supplierid") %>' /><br />
 categoryid: <asp:label id="categoryidlabel" runat="server"
    text='<%# eval("categoryid") %>'/><br />
 quantityperunit: <asp:label id="quantityperunitlabel" runat="server"
    text='<%# eval("quantityperunit") %>' /><br />
 unitprice: <asp:label id="unitpricelabel" runat="server"
    text='<%# eval("unitprice") %>' /><br />
 unitsinstock: <asp:label id="unitsinstocklabel" runat="server"
    text='<%# eval("unitsinstock") %>' /><br />
 unitsonorder: <asp:label id="unitsonorderlabel" runat="server"
    text='<%# eval("unitsonorder") %>' /><br />
 reorderlevel: <asp:label id="reorderlevellabel" runat="server"
    text='<%# eval("reorderlevel") %>' /><br />
 discontinued: <asp:label id="discontinuedlabel" runat="server"
    text='<%# eval("discontinued") %>' /><br />
 categoryname: <asp:label id="categorynamelabel" runat="server"
    text='<%# eval("categoryname") %>' /><br />
 suppliername: <asp:label id="suppliernamelabel" runat="server"
    text='<%# eval("suppliername") %>' /><br />
 <br />
 </itemtemplate>
</asp:datalist>
<asp:objectdatasource id="objectdatasource1" runat="server"
 oldvaluesparameterformatstring="original_{0}"
 selectmethod="getproducts" typename="productsbll">
</asp:objectdatasource>

  注意:当通过智能标签将数据源绑定到formview 时,vistual studio会创建一个itemtemplate,一个insertitemtemplate和一个edititemtemplate.然而对datalist来说,只会创建一个itemtemplate .这是因为datalist 不象formview那样,有内置的编辑和插入功能.datalist 没有编辑和删除相关的事件,虽然要完成这些功能,对datalist 来说没有formview那么简单,我们仍然可以加少量代码来实现它.我们在以后的教程里会讲到如何在datalist 里完成编辑和删除的功能.

  让我们花点时间来改善一下模板的外观.我们只显示product的name,supplier,category,数量和单价.而且我们用<h4> 来显示名字,其它字段都放在 <h4>heading下的<table>里.你可以通过datalist的只能标签里的 edit templates ,或者直接修改页面声明语法来达到以上目的.如果你是通过edit templates 来实现,那你的页面代码可能和下面的不完全一样.但是通过浏览器浏览你的页面应该和图8看起来差不多.

<asp:datalist id="datalist1" runat="server" datakeyfield="productid"
 datasourceid="objectdatasource1" enableviewstate="false">
 <itemtemplate>
 <h4><asp:label id="productnamelabel" runat="server"
  text='<%# eval("productname") %>' /></h4>
 <table border="0">
  <tr>
  <td class="productpropertylabel">category:</td>
  <td><asp:label id="categorynamelabel" runat="server"
   text='<%# eval("categoryname") %>' /></td>
  <td class="productpropertylabel">supplier:</td>
  <td><asp:label id="suppliernamelabel" runat="server"
   text='<%# eval("suppliername") %>' /></td>
  </tr>
  <tr>
  <td class="productpropertylabel">qty/unit:</td>
  <td><asp:label id="quantityperunitlabel" runat="server"
   text='<%# eval("quantityperunit") %>' /></td>
  <td class="productpropertylabel">price:</td>
  <td><asp:label id="unitpricelabel" runat="server"
   text='<%# eval("unitprice", "{0:c}") %>' /></td>
  </tr>
 </table>
 </itemtemplate>
</asp:datalist>

  注意:上面的例子使用的是text指定为数据绑定的值的label控件.我们也可以不使用label,而只是保留数据绑定的代码.也就是说,我们可以用<%# eval("categoryname") %>来代替<asp:label id="categorynamelabel" runat="server" text='<%# eval("categoryname") %>' />.

  使用label控件有两个好处,第一点在下一章我们会看到,就是提供了一个格式化数据的简单途径.第二点是不使用web控件的时候,edit templates 不显示声明的数据绑定代码.通过edit templates 的界面很容易操作静态标记语言和web控件,其前提是所有的数据绑定都是通过web控件的智能标签里的edit databindings对话框来实现.因此,使用datalist的时候,我建议使用label控件,这样通过edit templates 就可以操作其内容.我们会看到,使用repeater 时如果需要编辑其内容,需要切换到源视图.而设计repeater模板的时候,我通常不使用label控件,除非我需要格式化绑定数据的外观.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 8:  用datalist的 itemtemplate显示product

第三步: 改善datalist的外观

  和gridview一样,datalist 提供了一些和风格有关的属性,比如font, forecolor, backcolor, cssclass, itemstyle, alternatingitemstyle, selecteditemstyle等.当使用 gridview 和detailsview 时,我们首先在datawebcontrols theme里创建了一些皮肤文件,这些文件预定义了这两个控件的cssclass 属性和rowstyle, headerstyle等.我们使用datalist的时候也采取这种方法.

  象在使用objectdatasource展现数据 里谈到的那样,一个skin 文件定义了一个web控件的默认显示属性.一个theme 是一组skin, css, image, 和javascript files 的集合,它定义了一个web站点的外观.在使用objectdatasource展现数据 那一章里,我们创建了一个datawebcontrols  theme(app_themes 文件夹下) ,它包含两个skin文件- gridview.skin 和detailsview.skin.我们现在来为datalist添加第三个.右键单击app_themes/datawebcontrols 文件夹,选择add a new item,选择skin file,在名字里填datalist.skin.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 9: 创建一个名为datalist.skin的skin文件

将下面的标记语言添加到datalist.skin里.

<asp:datalist runat="server" cssclass="datawebcontrolstyle">
 <alternatingitemstyle cssclass="alternatingrowstyle" />
 <itemstyle cssclass="rowstyle" />
 <headerstyle cssclass="headerstyle" />
 <footerstyle cssclass="footerstyle" />
 <selecteditemstyle cssclass="selectedrowstyle" />
</asp:datalist>

  上面用gridview 和detailsview 使用的css文件设置datalist .在datawebcontrolstyle, alternatingrowstyle, rowstyle里用到的css文件是在styles.css 里定义的.

  添加完skin后,datalist的外观看起来会变了(你可以在视图菜单里选择刷新来看改变后的效果).见图10,alternating product 的背景色为粉红色.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 10: 添加skin文件后的效果

第四步: 浏览datalist的其它templates

datalist 还支持除了itemtemplate外的其它6种template:

headertemplate — 用来呈现 header row
alternatingitemtemplate — 用来呈现alternating items
selecteditemtemplate — 用来呈现selected item; selected item 的index 可以通过datalist 的 selectedindex property 得到
edititemtemplate — 用来呈现被编辑的item
separatortemplate — 用来分隔各个item
footertemplate - 用来呈现footer row

  当指定headertemplate 或footertemplate时,datalist 会加一个header 或footer .和gridview一样,datalist 的header 和footer 没有和数据绑定在一起.

  注意:如我们在在gridview的页脚中显示统计信息 一章里看到的那样,header 和footer 不支持数据绑定语法,而数据绑定的信息可以通过gridview的rowdatabound event handler来写.这个技术可以用来技术绑定的数据的和或其它信息,并在footer里显示.同样的,可以在datalist 和repeater 里面这样做.它们唯一的区别在于对datalist 和repeater 来说是为itemdatabound 创建event handler (而不是rowdatabound ).

  在我们的例子里,我们将标题“product information”用<h3> 显示在datalist的results 的顶部.为了达到这个目的,在headertemplate 中添加合适的标记语言.或者通过datalist的智能标签中的edit templates 来实现.从下拉列表中选择header template ,从style 下拉列表中选择heading 3 并输入text(见图11).

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 11: 添加text 为“product information”的headertemplate

同样,直接在<asp:datalist>标记里加入以下代码也可以达到上面的目的.

<headertemplate>
 <h3>product information</h3>
</headertemplate>

为了在每个列出的product 之间保留一些空间,我们现在来添加一个separatortemplate .<hr>标签可以完成这种分割的功能.见下面的标记语言

<separatortemplate>
 <hr />
</separatortemplate>
           

注意:与headertemplate 和footertemplates一样,separatortemplate 并不和数据源里的任何数据绑定.因此,并不能直接的和datalist绑定的数据发生关系.

现在在浏览器里浏览这个页面,看起来应该和图12差不多.注意header 和各个product 之间的线.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 12: datalist 现在包含了 header row 和每个product 之间有一条线

第五步: 使用repeater

  在浏览图12的例子时,你可以看看页面的源文件.你会看到datalist 包含有<tr>和<td>标记的html<table>.这个实际上和gridview一样.我们会在将来的教程里看到,datalist允许每一行显示多条记录.

  但如果你不想使用html<table>呢?我们将使用repeater .repeater 也是基于templates构建的.它提供以下5种template:

headertemplate — 在items前加指定的标记
itemtemplate — 用来呈现items
alternatingitemtemplate — 用来呈现alternating items
separatortemplate —在各个item 之间加指定的标记
footertemplate - 在items后加指定的标记

  在asp.net  1.x版本里.repeater 通常用来显示一些数据列.在这种情况下,headertemplate 和footertemplates 包含一对<ul>标记,而itemtemplate 包含 <li> 和数据绑定语法.这种方法在asp.net 2.0也适用,比如我们在母板页和站点导航一章里看到的例子:

  在site.master母板页里,  repeater 用来显示*站点内容(basic reporting, filtering reports, customized formatting, and so on); 嵌套的repeater 用来显示 子区域的内容.
在sectionleveltutoriallisting.ascx用户控件里, repeater 用来显示当前站点区域的子区域内容.

  注意:asp.net 2.0可以使用bulletedlist control.使用它的时候不需要指定任何和list有关的html.而仅仅是指定每个list item的字段.

  repeater 是一个"全能"的控件,如果你找不到控件可以产生需要的标记语言,那么可以使用repeater .我们来举例说明,在第二步里创建的显示product信息的datalist上显示出categoried.我们将每个categorie作为一列显示在单行的html<table>里.从工具箱里拖一个repeater 到显示product 的datalist上.和datalist一样,在定义templates前,repeater 是灰色的.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 13: 添加一个 repeater 控件

在repeater 的智能标签里只有一个可选项:选择数据源.创建一个objectdatasource ,用categoriesbll 类的getcategories 方法配置它.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 14: 创建objectdatasource

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 15: 用 categoriesbll 类配置objectdatasource

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图16: 用 getcategories method获取所有categories的信息

和datalist不一样,在绑定到数据源后,visual studio不会为repeater 自动创建itemtemplate .而且repeater 的templates 不能通过设计器来配置,只能写页面代码.

我们用如下标记来将每个category作为一列显示在单行的<table>里:

<table>
 <tr>
  <td>category 1</td>
  <td>category 2</td>
  ...
  <td>category n</td>
 </tr>
</table>

  由于<td>category x</td>是重复的一部分,因此会显示在repeater的itemtemplate里.在它之前的标记<table><tr>会放在headertemplate里,而结束标记</tr></table>会放在footertemplate里.在设计器的左下角点源视图按钮进入asp.net页的声明代码部分,输入以下代码:

<asp:repeater id="repeater1" runat="server" datasourceid="objectdatasource2"
 enableviewstate="false">
 <headertemplate>
  <table>
   <tr>
 </headertemplate>
 <itemtemplate>
    <td><%# eval("categoryname") %></td>
 </itemtemplate>
 <footertemplate>
   </tr>
  </table>
 </footertemplate>
</asp:repeater>

repeater 精确的包含在它模板里指定的标记,不会有任何多余的部分.图17显示通过浏览器浏览repeater的样子.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 17: 在单行的html <table> 用单独的列列出每个category

第六步: 改善repeater的外观

  既然repeater 是精确呈现在templates里指定的标记,那么你应该可以想到它不包含任何和风格有关的属性.为了改变repeater产生的内容的外观,我们需要手动的将html或css加到它的templates里.

  在这个例子里,我们将做一个类似datalist的alternating rows那样的东西,改变category 的背景色.我们通过itemtemplate 和alternatingitemtemplate 来为每个repeater item 指定rowstyle css class ,为每个alternating repeater item 指定alternatingrowstyle css class ,象下面的代码一样:

<itemtemplate>
 <td class="rowstyle"><%# eval("categoryname") %></td>
</itemtemplate>
<alternatingitemtemplate>
 <td class="alternatingrowstyle"><%# eval("categoryname") %></td>
</alternatingitemtemplate>

  我们还要添加一个text为“product categories”的header .由于我们不知道 <table>会由多少列组成,最简单的方法保证产生的header 可以跨越所有的列是使用两个<table>.第一个<table>包含两行 — header 和一行包含第二个 <table>的行.第二个 <table>里每个category 为一列.

<table>
 <tr>
  <th>product categories</th>
 </tr>
 <tr>
  <td>
   <table>
   <tr>
    <td>category 1</td>
    <td>category 2</td>
    ...
    <td>category n</td>
   </tr>
   </table>
  </td>
 </tr>
</table>

下面的 headertemplate 和footertemplate 产生需要的标记:

<asp:repeater id="repeater1" runat="server" datasourceid="objectdatasource2"
 enableviewstate="false">
 <headertemplate>
  <table cellpadding="0" cellspacing="0">
   <tr>
    <th class="headerstyle">product categories</th>
   </tr>
   <tr>
    <td>
     <table cellpadding="4" cellspacing="0">
      <tr>
 </headertemplate>
 <itemtemplate>
       <td class="rowstyle"><%# eval("categoryname") %></td>
 </itemtemplate>
 <alternatingitemtemplate>
       <td class="alternatingrowstyle">
        <%# eval("categoryname") %></td>
 </alternatingitemtemplate>
 <footertemplate>
      </tr>
     </table>
    </td>
   </tr>
  </table>
 </footertemplate>
</asp:repeater>
         

图18 里可以看到现在repeater的样子.

在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据

图 18:  category 列的背景色交替变换and includes a header row

总结

  虽然使用gridview 来显示,编辑,删除,排序和分页数据都非常容易,但是很臃肿.为了更好的控制外观,我们需要使用datalist 或repeater .这些控件使用templates 来显示记录,而不是boundfields.

  datalist 包含一个html <table>,默认情况下table的一行显示数据源的一条记录,和gridview一样.我们在以后的教程里会看到,datalist 可以在一个table 行里表示多条记录.而另一方面,repeater严格的显示在templates指定的标记.它不会添加任何额外的信息,因此通常被用来在除了 <table> 以外的html元素里显示数据.

  datalist 和repeater 在输出上提供了更大的灵活性,而和gridview相比,它们又缺少很多内置的特性.在以后的教程里我们会看到,有一些特性我们可以很简单的加上.但是要记住,使用datalist 和repeater而不是gridview ,如果想使用这些特性的话,你必须去实现它们.

  祝编程快乐!

作者简介

  scott mitchell,著有六本asp/asp.net方面的书,是4guysfromrolla.com的创始人,自1998年以来一直应用 微软web技术。scott是个独立的技术咨询顾问,培训师,作家,最近完成了将由sams出版社出版的新作,24小时内精通asp.net 2.0。他的联系电邮为,也可以通过他的博客http://scottonwriting.net与他联系。

上一篇:

下一篇: