导言

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

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


1: “show products” 显示目录下所有product

第一步: 添加教程页

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

  • default.aspx
  • custombuttons.aspx


2: 添加页

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


3: 添加 sectionleveltutoriallisting.ascx用户控件

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

xml

 

 

<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。


4: 现在的站点地图包含了本章的页

第二步: 添加 categories列表

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


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.net

 

<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,但是还不执行任何功能。


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") %>‘)解决ItemCommand事件取当行绑定ID的问题)。完成这些后,linkbutton的声明语法看起来应该和下面差不多:

asp.net

<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.net

<asp:bulletedlist id="productsincategory" datatextfield="productname"

    runat="server"></asp:bulletedlist>

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

c#

 

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的教程里,比如an overview of editing and deleting data in the 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。


7: bulletedlist 显示选择category关联的 products.

总结

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

posted on 2007-08-24 10:51  绿毛虫  阅读(1163)  评论(0编辑  收藏  举报