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

作者 :Scott Mitchell

下载 PDF

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

简介

在过去的 17 个 DataList 和 Repeater 教程中,我们创建了只读示例以及编辑和删除示例。 为了方便 DataList 中的编辑和删除功能,我们向 DataList ItemTemplate 添加了按钮,单击这些按钮时会导致回发并引发对应于按钮属性的 CommandName DataList 事件。 例如,向 属性值为 Edit 的 添加按钮ItemTemplate会导致 DataList 在EditCommand回发时触发;带有 Delete 的CommandName按钮将引发 DeleteCommandCommandName

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

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

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

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

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

  • Default.aspx
  • CustomButtons.aspx

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

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

与其他文件夹中一样, Default.aspx 文件夹中 CustomButtonsDataListRepeater 会列出其部分的教程。 回想一下, 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:添加类别列表

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

配置 ObjectDataSource 以使用 CategoriesBLL 类 getCategories () 方法

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

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

单击左下角的“源”选项卡,添加一个 ItemTemplate ,该选项卡在元素中 <h3> 显示类别名称,并在段落标记中显示其说明;包括一个 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 显示了通过浏览器查看时的页面。 列出了每个类别名称和说明。 单击“显示产品”按钮会导致回发,但尚未执行任何操作。

显示每个类别的名称和说明,以及显示产品 LinkButton

图 6:显示每个类别的名称和说明,以及显示产品 LinkButton (单击以查看全尺寸图像)

步骤 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 事件 ItemCommand 创建事件处理程序,并记下传递到事件处理程序的第二个参数 (名为 e) 。 第二个参数的类型 RepeaterCommandEventArgs 为 ,具有以下四个属性:

  • CommandArgument 单击的按钮属性 CommandArgument 的值
  • CommandName 按钮属性 CommandName 的值
  • CommandSource 对单击的按钮控件的引用
  • ItemRepeaterItem 包含已单击按钮的 的引用;绑定到中继器的每个记录都显示为 RepeaterItem

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

注意

向 DataList 的 ItemCommand 事件处理程序传递类型为 DataListCommandEventArgs的对象,该对象提供与 类相同的四个 RepeaterCommandEventArgs 属性。

步骤 4:在项目符号列表中显示所选类别的产品

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

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

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

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执行任何操作之前,最好先检查传入 CommandName的值。 由于事件处理程序会在 ItemCommand 单击 任何 按钮时触发,因此如果模板中有多个按钮, CommandName 请使用 值来识别要执行的操作。 CommandName检查这里是没有意义的,因为我们只有一个按钮,但它是一个很好的习惯形成。 接下来, CategoryID 从 属性检索所选类别的 CommandArgument 。 然后,模板中的 BulletedList 控件将被引用并绑定到 类方法GetProductsByCategoryID(categoryID)的结果ProductsBLL

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

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

注意

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

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

图 7:BulletedList 用于显示所选类别的产品 (单击以查看全尺寸图像)

总结

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

编程愉快!

关于作者

Scott Mitchell 是七本 ASP/ASP.NET 书籍的作者, 4GuysFromRolla.com 的创始人,自 1998 年以来一直从事 Microsoft Web 技术工作。 Scott 担任独立顾问、培训师和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0自学。 可以在 上联系 mitchell@4GuysFromRolla.com他, 也可以通过他的博客联系到他,该博客可在 http://ScottOnWriting.NET中找到。

特别感谢

本教程系列由许多有用的审阅者查看。 本教程的首席审阅者是 Dennis Patterson。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处放置一行 mitchell@4GuysFromRolla.com。