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

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button

程序员文章站 2023-12-13 11:41:28
导言   在前面关于datalist 和repeater 的7章教程里,我们分别创建了只读和可以编辑删除的例子。为了让datalist有编辑和删除的功能,我们在itemt...

导言

  在前面关于datalist 和repeater 的7章教程里,我们分别创建了只读和可以编辑删除的例子。为了让datalist有编辑和删除的功能,我们在itemtemplate里添加了一些button,当点击时,引起postback,并根据button的commandname属性激发相关的事件。例如,添加一个commandname为“edit”的button,在postback时会激发editcommand事件,如果commandname为“delete”则激发deletecommand。

  除了编辑和删除button,datalist和repeater还可以包含一些当点击时,执行自定义服务器端逻辑的button,linkbutton和imagebutton。本章我们将创建一个在repeater里列出categories的界面。每个category都包含一个button,当点击时会列出相关product。见图1。

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图 1: 点 “show products” 显示目录下所有product

第一步: 添加教程页

首先添加本章需要的页。添加一个名为custombuttonsdatalistrepeater的文件夹。然后添加下面两个页,记得包含site.master母板页。

    default.aspx
    custombuttons.aspx

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图 2: 添加页

和其它文件夹一样,custombuttonsdatalistrepeater文件夹下的default.aspx页会列出本部分的教程。和前面一样添加sectionleveltutoriallisting.ascx用户控件。

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图 3: 添加 sectionleveltutoriallisting.ascx用户控件

最后,在web.sitemap里添加这些页的信息。见下面的标记:

<sitemapnode
 url="~/custombuttonsdatalistrepeater/default.aspx"
 title="adding custom buttons to the datalist and repeater"
 description="samples of datalist and repeater reports that include
     buttons for performing server-side actions">
 <sitemapnode
  url="~/custombuttonsdatalistrepeater/custombuttons.aspx"
  title="using custom buttons in the datalist and repeater's templates"
  description="examines how to add custom buttons, linkbuttons,
      or imagebuttons within templates." />
</sitemapnode>

完成后浏览该页。见图4。

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图 4: 现在的站点地图包含了本章的页

第二步: 添加 categories列表

  我们需要添加一个列出所有categories,每个category都有一个“show products” linkbutton的repeater。点linkbutton时会显示所有category相关的products。我们首先创建一个列出所有categories的repeater。打开custombuttons.aspx页,拖一个repeater进来,将id设为categories。然后从智能标签里创建一个名为categoriesdatasource的objectdatasource,用categoriesbll类的getcategories()方法配置它。

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图5: 配置objectdatasource

  visual studio会根据数据源为datalist创建一个默认的itemtemplate,而repeater的templates需要手工定义。而且repeater的templates需要直接通过声明代码来创建和修改(也就是说在智能标签上没有“edit templates”选项)

  点左下角的源视图,添加一个以<h3>显示category name,以段落description的itemtemplate。并包含一个在每个category之间显示水平线(<hr />)的separatortemplate。同样还要添加一个linkbutton,将text设为“show products”。完成这些后你的页面声明代码应该和下面差不多:

<asp:repeater id="categories" datasourceid="categoriesdatasource"
 runat="server">
 <itemtemplate>
  <h3><%# eval("categoryname") %></h3>
  <p>
   <%# eval("description") %>
   [<asp:linkbutton runat="server" id="showproducts">
    show products</asp:linkbutton>]
  </p>
 </itemtemplate>
 <separatortemplate><hr /></separatortemplate>
</asp:repeater>
<asp:objectdatasource id="categoriesdatasource" runat="server"
 oldvaluesparameterformatstring="original_{0}"
 selectmethod="getcategories" typename="categoriesbll">
</asp:objectdatasource>

  图6是浏览该页的样子。每个category name和description都被列出来。当点“show products” button时会引起postback,但是还不执行任何功能。

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图 6: 每个 category'的name 和 description 和 “show products” linkbutton一起列出

第三步:当点“show products” linkbutton 时执行服务器端代码

  任何时候,当datalist或repeater的template里的button, linkbutton, imagebutton被点时,会产生postback,并激发datalist或repeater的itemcommand事件。除了itemcommand外,如果button'的commandname 设为(“delete”, “edit”, “cancel”, “update”,  “select”)其中一个时,datalist会激发另外一个事件。但是itemcommand是都会激发的。

  当datalist或repeater的template里的button被点时,通常我们需要获取哪个button被点了(一个控件里可能有多个button,比如编辑和删除),还可能需要一些其它的信息(比如那些button被点的item(项)的主键)。button, linkbutton, imagebutton提供了两个属性,它们的值可以传给itemcommand event handler:

    commandname –表示template里每个button身份的字符串 。
    commandargument – 通常用来保存一些值,比如主键。

  在这个例子里,将linkbutton的commandname设为“showproducts”,并将当前记录的主键– categoryid –通过绑定语法绑定到commandargument(categoryargument='<%# eval("categoryid") %>')。完成这些后,linkbutton的声明语法看起来应该和下面差不多:

<asp:linkbutton runat="server" commandname="showproducts"
 commandargument='<%# eval("categoryid") %>' id="showproducts">
 show products</asp:linkbutton>

  当button被点时,产生postback并激发datalist或repeater的itemcommand事件。button的commandname和commandargument值被传到event handler里。

  为itemcommand事件创建一个event handler,注意event handler的第二个参数(名字为e)。这个参数的类型为repeatercommandeventargs,它有以下4个属性:

    commandargument – 被点的 button'的commandargument property 的值
    commandname –  button'的commandname property 的值
    commandsource – 被点 button 的引用
    item – 包含被点button 的 repeateritem的引用; 每条绑定到repeater的记录被表明为一个 repeateritem

  由于选择的category的categoryid通过commandargument传入,我们可以在itemcommand event handler里获取与之相关的products。这些products在itemtemplate(我们已经添加过了)里绑定到一个bulletedlist。剩下的事就是添加bulletedlist,在itemcommand event handler里引用它,然后将选择的category的products绑定到bulletedlist,我们将在第四步完成这个。

  注意:datalist的itemcommand event handler传入了一个datalistcommandeventargs类型的对象,它提供和repeatercommandeventargs 一样的4个属性。

第四步: 显示选择的category的 products

  在itemtemplate里显示products可以使用很多控件,我们可以添加一个嵌套的repeater,datalist,dropdownlist,gridview等。在这里我们使用bulletedlist。回到custombuttons.aspx page页的声明代码,在“show products” linkbutton后添加一个bulletedlist。将id设为productsincategory。bulletedlist显示那些通过datatextfield属性指定的字段值。由于将有product信息绑定到这个属性,我们将datatextfield设为productname。

<asp:bulletedlist id="productsincategory" datatextfield="productname"
 runat="server"></asp:bulletedlist>

在itemcommand event handler里通过e.item.findcontrol("productsincategory")引用这个控件,并与products绑定。

protected void categories_itemcommand(object source, repeatercommandeventargs e)
{
 if (e.commandname == "showproducts")
 {
  // determine the categoryid
  int categoryid = convert.toint32(e.commandargument);
  // get the associated products from the proudctsbll and bind
  // them to the bulletedlist
  bulletedlist products =
   (bulletedlist)e.item.findcontrol("productsincategory");
  productsbll productsapi = new productsbll();
  products.datasource =
   productsapi.getproductsbycategoryid(categoryid);
  products.databind());
 }
}

  在itemcommand event handler里执行任何操作前,需要先检查传入的commandname。由于itemcommand event handler在任何button被点时都会执行,如果在template里有多个button时需要通过commandname的值来辨别需要采取什么操作。由于我们这里只有一个button,因此在这里检查commandname是没意义的,但是这是一个好习惯。然后,选择的category的categoryid通过commandargument获取。然后引用template里的bulletedlist并绑定productsbll类的getproductsbycategoryid(categoryid)方法的结果。

  在前面datalist里使用button的教程里,比如在datalist里编辑和删除数据概述,我们通过datakeys集合来获取给定item的主键。这个方法在datalist里很好用,但是repeater没有datakeys属性。因此我们需要换一种方法来提供主键的值,比如通过button的 commandargument,或者在template使用一个隐藏的label,然后通过e.item.findcontrol("labelid")在itemcommand event handler里读出它的值。

  完成itemcommand event handler后,浏览该页。见图7。点“show products” link会引起postback,并显示相关的products。而且,注意当点其它“show products” links时前面的product信息会保留。

  注意:如果你需要修改这个报表的行为,比如一次只列出一个category的products,仅仅只需要将bulletedlist的enableviewstate属性设为false。

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button
图 7: 用 bulletedlist 显示选择category关联的 products.

总结

  datalist和repeater可以在templates里包含很多buttons, linkbuttons,  imagebuttons。这些button被点时会引起postback,并激发itemcommand事件。为itemcommand event.创建一个event handler可以将服务器端代码和点击button关联起来。在这个event handler里首先检查传入的commandname的值来判断是哪个button被点了。其它另外的信息可以通过commandargument属性来提供。

  祝编程快乐!

作者简介

  本系列教程作者 scott mitchell,著有六本asp/asp.net方面的书,是4guysfromrolla.com的创始人,自1998年以来一直应用 微软web技术。大家可以点击查看全部教程《[翻译]scott mitchell 的asp.net 2.0数据教程》,希望对大家的学习asp.net有所帮助。

上一篇:

下一篇: