DataList 和 Repeater 中的自定义按钮 (VB)

作者 :斯科特·米切尔

下载 PDF

在本教程中,我们将生成一个接口,该接口使用 Repeater 列出系统中的类别,每个类别都提供一个按钮来使用 BulletedList 控件显示其关联的产品。

介绍

在过去的 17 个 DataList 和 Repeater 教程中,我们创建了只读示例和编辑和删除示例。 为了方便在 DataList 中进行编辑和删除操作,我们在 DataList 的 ItemTemplate 上添加了按钮,这些按钮在被单击时,会导致回发并触发与按钮的 CommandName 属性相对应的 DataList 事件。 例如,在具有CommandName属性值“编辑”的ItemTemplate上添加一个按钮,会导致 DataList 在EditCommand回发时触发事件;而带有CommandName“删除”的按钮则会引发DeleteCommand事件。

除了“编辑和删除”按钮之外,DataList 和 Repeater 控件还可以包括按钮、LinkButton 或 ImageButtons,单击时,执行一些自定义服务器端逻辑。 在本教程中,我们将生成一个接口,该接口使用 Repeater 列出系统中的类别。 对于每个类别,Repeater 将包含一个按钮,用于使用 BulletedList 控件显示类别的关联产品(请参阅图 1)。

单击“显示产品链接”在项目符号列表中显示类别的产品

图 1:单击“显示产品链接”显示项目符号列表中的类别产品(单击以查看全尺寸图像

步骤 1:添加自定义按钮教程网页

在了解如何添加自定义按钮之前,让我们先花点时间在网站项目中创建本教程所需的 ASP.NET 页面。 首先添加名为 <a0/a0> 的新文件夹。 接下来,将以下两个 ASP.NET 页添加到该文件夹中,确保将每个页面与 Site.master 母版页相关联:

  • Default.aspx
  • CustomButtons.aspx

为自定义 Buttons-Related 教程添加 ASP.NET 页面

图 2:为自定义 Buttons-Related 教程添加 ASP.NET 页

与其他文件夹中一样, Default.aspxCustomButtonsDataListRepeater 文件夹中将列出其部分中的教程。 回想一下, SectionLevelTutorialListing.ascx 用户控件提供了此功能。 通过从解决方案资源管理器将此用户控件拖动到Default.aspx页面的设计视图来添加该控件。

将 SectionLevelTutorialListing.ascx 用户控件添加到 Default.aspx

图 3:将用户控件SectionLevelTutorialListing.ascx添加到 Default.aspx单击以查看全尺寸图像

最后,将页面添加为文件的条目 Web.sitemap 。 具体而言,在使用 DataList 和 Repeater 进行分页和排序之后,添加以下标记 <siteMapNode>

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

更新 Web.sitemap后,请花点时间通过浏览器查看教程网站。 左侧菜单现在包括用于编辑、插入和删除教程的项目。

网站地图现在包括自定义按钮教程的条目

图 4:网站地图现在包括自定义按钮教程的条目

步骤 2:添加类别列表

在本教程中,我们需要创建一个 Repeater,它列出所有类别,并包含一个名为“显示产品”的 LinkButton,单击后,会在项目符号列表中显示关联的类别产品。 首先创建一个简单的 Repeater,用于列出系统中的类别。 首先打开 CustomButtons.aspx 文件夹中的页面 CustomButtonsDataListRepeater 。 将 Repeater 从工具箱拖到设计器上,并将其 ID 属性设置为 Categories。 接下来,从 Repeater 的智能标记创建新的数据源控件。 具体而言,创建一个名为CategoriesDataSource的新 ObjectDataSource 控件,该控件从类CategoriesBLL的方法GetCategories()中选择其数据。

将 ObjectDataSource 配置为使用 CategoriesBLL 类 s GetCategories() 方法

图 5:将 ObjectDataSource 配置为使用 CategoriesBLL 类 s GetCategories() 方法(单击以查看全尺寸图像

与 Visual Studio 基于数据源创建默认值 ItemTemplate 的 DataList 控件不同,必须手动定义 Repeater 的模板。 此外,必须以声明方式创建和编辑 Repeater 的模板(也就是说,Repeater 智能标记中没有“编辑模板”选项)。

单击左下角的“源”选项卡,在 <h3> 元素中添加一个 ItemTemplate 来显示类别名称,并在段落标签中显示其说明;还包括一个 SeparatorTemplate ,用于在每个类别之间显示一条水平线(<hr />)。 此外,请添加一个 LinkButton,并将其 Text 属性设置为“显示产品”。 完成这些步骤后,页面的声明性标记应如下所示:

<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 显示通过浏览器查看的页面。 列出了每个类别名称和说明。 单击“显示产品”按钮会导致回发,但尚未执行任何操作。

显示每个类别的名称和说明,并附带一个“显示产品”链接按钮

图 6:显示每个类别的名称和说明,并带有一个显示产品的链接按钮(单击以查看全尺寸图像

步骤 3:单击“显示产品”链接按钮时执行 Server-Side 逻辑

每当单击 DataList 或 Repeater 中模板内的 Button、LinkButton 或 ImageButton 时,就会发生回发,并触发 DataList 或 Repeater 的事件 ItemCommand。 除了ItemCommand事件之外,如果按钮CommandName的属性设置为保留字符串之一(删除、编辑、取消、更新或选择),DataList 控件也可能引发另一个更具体的事件,但ItemCommand事件始终会触发。

在 DataList 或 Repeater 中单击某个按钮时,通常需要传递单击的按钮(在这种情况下,控件中可能存在多个按钮,例如“编辑”和“删除”按钮)和一些附加信息(例如单击按钮的项目的主键值)。 Button、LinkButton 和 ImageButton 提供两个属性,其值将 ItemCommand 传递给事件处理程序:

  • CommandName 通常用于标识模板中的每个按钮的字符串
  • CommandArgument 通常用于保存某些数据字段的值,例如主键值

对于此示例,请将 LinkButton s CommandName 属性设置为 ShowProducts,并使用数据绑定语法CategoryArgument='<%# Eval("CategoryID") %>'将当前记录的主键值CategoryID绑定到CommandArgument属性。 指定这两个属性后,LinkButton 的声明性语法应如下所示:

<asp:LinkButton runat="server" CommandName="ShowProducts"
    CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">
    Show Products</asp:LinkButton>

单击该按钮时,将发生回发,然后 DataList 或 Repeater 的 ItemCommand 事件触发。 事件处理程序被传递按钮的CommandNameCommandArgument值。

为 Repeater s ItemCommand 事件创建事件处理程序,并记下传递到事件处理程序(命名 e)中的第二个参数。 第二个参数的类型 RepeaterCommandEventArgs 如下,具有以下四个属性:

  • CommandArgument 单击的按钮的CommandArgument 属性的值
  • CommandName 按钮 s CommandName 属性的值
  • CommandSource 对被点击的按钮控件的引用
  • Item 是对包含已单击按钮的 RepeaterItem 的引用;绑定到 Repeater 的每个记录都显示为 RepeaterItem

由于所选类别 CategoryID 是通过 CommandArgument 属性传入的,因此我们可以获取与事件处理程序中 ItemCommand 所选类别关联的产品集。 然后,这些产品可以绑定到项目符号列表控件(我们尚未添加的ItemTemplate中)。 然后,剩下的就是添加 BulletedList,在 ItemCommand 事件处理程序中引用它,并将其绑定到所选类别的产品集,我们将在步骤 4 中处理。

注释

DataList 的 ItemCommand 事件处理程序接收到一个类型为 DataListCommandEventArgs 的对象,该对象提供了与 RepeaterCommandEventArgs 类相同的四个属性。

步骤 4:以项目列表形式显示所选类别的产品

所选类别的产品可以使用任意数量的控件显示在 Repeater s ItemTemplate 中。 我们可以添加另一个嵌套的 Repeater、DataList、DropDownList、GridView 等。 但是,由于我们希望将产品显示为项目符号列表,因此我们将使用 BulletedList 控件。 返回到 CustomButtons.aspx 页面的声明性标记,将 BulletedList 控件添加到 ItemTemplate “显示产品链接按钮”之后。 将 BulletedLists ID 设置为 ProductsInCategory. BulletedList 显示通过 DataTextField 属性指定的数据字段的值。由于此控件将具有绑定到该字段的产品信息,因此请将 DataTextField 属性设置为 ProductName

<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"
    runat="server"></asp:BulletedList>

ItemCommand事件处理程序中,使用e.Item.FindControl("ProductsInCategory")引用此控件,并将其绑定到与所选类别相关联的所有产品集。

Protected Sub Categories_ItemCommand _
    (source As Object, e As RepeaterCommandEventArgs) _
    Handles Categories.ItemCommand
    If e.CommandName = "ShowProducts" Then
        ' Determine the CategoryID
        Dim categoryID As Integer = Convert.ToInt32(e.CommandArgument)
        ' Get the associated products from the ProudctsBLL and
        ' bind them to the BulletedList
        Dim products As BulletedList = _
            CType(e.Item.FindControl("ProductsInCategory"), BulletedList)
        Dim productsAPI As New ProductsBLL()
        products.DataSource = productsAPI.GetProductsByCategoryID(categoryID)
        products.DataBind()
    End If
End Sub

ItemCommand 的事件处理程序中执行任何操作之前,最好先检查传入 CommandName 的值。 ItemCommand由于事件处理程序会在单击任何按钮时触发,因此如果模板中有多个按钮,CommandName的值可用来确定要执行的操作。 对CommandName进行检查在这里显得毫无意义,因为我们只有一个按钮,但养成这个习惯是好的。 接下来,从CommandArgument属性中检索所选类别的CategoryID。 然后,引用模板中的 BulletedList 控件,并将其绑定到类ProductsBLL方法的GetProductsByCategoryID(categoryID)结果。

在之前使用 DataList 中的按钮(如 DataList 中编辑和删除数据的概述)的教程中,我们通过 DataKeys 集合确定了给定项的主键值。 虽然此方法适用于 DataList,但 Repeater 没有 DataKeys 属性。 相反,我们必须使用替代方法来提供主键值,例如,通过按钮的CommandArgument属性,或者将主键值分配给模板中的隐藏 Label Web 控件,并在ItemCommand事件处理程序中使用e.Item.FindControl("LabelID")读取其值。

完成 ItemCommand 事件处理程序后,花点时间在浏览器中测试此页面。 如图 7 所示,单击“显示产品”链接会导致回发,并在 BulletedList 中显示所选类别的产品。 此外,请注意,即使单击其他类别“显示产品”链接,此产品信息也会保留。

注释

如果要修改此报表的行为,以便一次只列出一个类别的产品,只需将 BulletedList 控件的属性 EnableViewState 设置为 False

BulletedList 用于显示所选类别的产品

图 7:项目符号列表用于显示所选类别的产品(单击以查看全尺寸图像

概要

DataList 和 Repeater 控件可以在模板中包含任意数量的按钮、LinkButton 或 ImageButton。 单击后,此类按钮会导致回发并引发 ItemCommand 事件。 若要将自定义服务器端动作与按钮单击事件相关联,请为ItemCommand事件创建事件处理器。 在此事件处理程序中,首先检查传入 CommandName 值以确定单击了哪个按钮。 可以选择通过按钮属性 CommandArgument 提供其他信息。

快乐编程!

关于作者

斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 《Sams Teach Yourself ASP.NET 2.0 in 24 Hours》。 可以通过 mitchell@4GuysFromRolla.com 联系到他。

特别致谢

本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是丹尼斯·帕特森。 有兴趣查看即将发布的 MSDN 文章? 如果是这样,请给我写信。mitchell@4GuysFromRolla.com