随笔 - 97  文章 - 0 评论 - 299 trackbacks - 434

原文 | 下载本教程中的编码例子 | 下载本教程的PDF版

导言

在前面关于DataList Repeater 7章教程里,我们分别创建了只读和可以编辑删除的例子。为了让DataList有编辑和删除的功能,我们在ItemTemplate里添加了一些button,当点击时,引起postback,并根据buttonCommandName属性激发相关的事件。例如,添加一个CommandName“Edit”button,在postback时会激发EditCommand事件,如果CommandName“Delete”则激发DeleteCommand

除了编辑和删除buttonDataListRepeater还可以包含一些当点击时,执行自定义服务器端逻辑的ButtonsLinkButtonsImageButtons。本章我们将创建一个在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

1

2

3

4

5

6

7

8

9

10

11

12

<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” LinkButtonRepeater。点LinkButton时会显示所有category相关的products。我们首先创建一个列出所有categoriesRepeater。打开CustomButtons.aspx页,拖一个Repeater进来,将ID设为Categories。然后从智能标签里创建一个名为CategoriesDataSourceObjectDataSource,用CategoriesBLL类的GetCategories()方法配置它。


5: 配置ObjectDataSource

Visual Studio会根据数据源为DataList创建一个默认的ItemTemplate,而Repeatertemplates需要手工定义。而且Repeatertemplates需要直接通过声明代码来创建和修改(也就是说在智能标签上没有“Edit Templates”选项)

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

ASP.NET

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<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 namedescription都被列出来。当点“Show Products” button时会引起postback,但是还不执行任何功能。


6: 每个 Category’Name Description “Show Products” LinkButton一起列出

第三步:当点“Show Products” LinkButton 时执行服务器端代码

任何时候,当DataListRepeatertemplate里的Button, LinkButton, ImageButton被点时,会产生postback,并激发DataListRepeaterItemCommand事件。除了ItemCommand外,如果button’CommandName 设为(“Delete”, “Edit”, “Cancel”, “Update”,  “Select”)其中一个时,DataList会激发另外一个事件。但是ItemCommand是都会激发的。

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

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

在这个例子里,将LinkButtonCommandName设为“ShowProducts”,并将当前记录的主键CategoryID通过绑定语法绑定到CommandArgumentCategoryArgument='<%# Eval("CategoryID") %>')。完成这些后,LinkButton的声明语法看起来应该和下面差不多:

ASP.NET

1

2

3

<asp:LinkButton runat="server" CommandName="ShowProducts"

    CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">

    Show Products</asp:LinkButton>

button被点时,产生postback并激发DataListRepeaterItemCommand事件。ButtonCommandNameCommandArgument值被传到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

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

注意:DataListItemCommand event handler传入了一个DataListCommandEventArgs类型的对象,它提供和RepeaterCommandEventArgs 一样的4个属性。

第四步: 显示选择的Category Products

ItemTemplate显示products可以使用很多控件,我们可以添加一个嵌套的RepeaterDataListDropDownListGridView等。在这里我们使用BulletedList。回到CustomButtons.aspx page页的声明代码,在“Show Products” LinkButton后添加一个BulletedList。将ID设为ProductsInCategoryBulletedList显示那些通过DataTextField属性指定的字段值。由于将有product信息绑定到这个属性,我们将DataTextField设为ProductName

ASP.NET

1

2

<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"

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

ItemCommand event handler里通过e.Item.FindControl("ProductsInCategory")引用这个控件,并与products绑定。

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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是没意义的,但是这是一个好习惯。然后,选择的categoryCategoryID通过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信息会保留。

注意:如果你需要修改这个报表的行为,比如一次只列出一个categoryproducts,仅仅只需要将BulletedListEnableViewState属性设为False


7: BulletedList 显示选择Category关联的 Products.

总结

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

 

posted on 2006-12-15 17:36 有些伤感 阅读(...) 评论(...) 编辑 收藏