添加和响应 GridView 的按钮 (VB)

作者 :斯科特·米切尔

下载 PDF

本教程介绍如何将自定义按钮添加到模板和 GridView 或 DetailsView 控件的字段。 具体而言,我们将生成一个具有 FormView 的接口,该接口允许用户分页浏览供应商。

介绍

虽然许多报告方案涉及对报表数据的只读访问权限,但报表并不罕见,包括根据显示的数据执行操作的能力。 通常,这涉及到添加一个 Button、LinkButton 或 ImageButton Web 控件,其中每个记录都显示在报表中,单击该记录时会导致回发并调用某些服务器端代码。 根据记录编辑和删除数据是最常见的示例。 事实上,从“插入、更新和删除数据概述”开始,编辑和删除操作非常常见,因此 GridView、DetailsView 和 FormView 控件可以支持此类功能,而无需编写单行代码。

除了“编辑和删除”按钮之外,GridView、DetailsView 和 FormView 控件还可以包括按钮、LinkButtons 或 ImageButtons,单击时,执行某些自定义服务器端逻辑。 本教程介绍如何将自定义按钮添加到模板和 GridView 或 DetailsView 控件的字段。 具体而言,我们将生成一个具有 FormView 的接口,该接口允许用户分页浏览供应商。 对于给定的供应商,FormView 将显示有关供应商的信息以及按钮 Web 控件,如果单击,则会将其所有关联产品标记为已停用。 此外,GridView 列出了所选供应商提供的这些产品,每行包含“提高价格”和“折扣价格”按钮,如果单击,则提高或减少产品的 UnitPrice 10%(请参阅图 1)。

FormView 和 GridView 都包含执行自定义操作的按钮

图 1:FormView 和 GridView 都包含执行自定义操作的按钮(单击以查看全尺寸图像

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

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

  • Default.aspx
  • CustomButtons.aspx

为自定义按钮相关的教程添加 ASP.NET 页面

图 2:为自定义按钮相关教程添加 ASP.NET 页面

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

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

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

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

<siteMapNode
    title="Adding Custom Buttons"
    description="Samples of Reports that Include Buttons for Performing
                  Server-Side Actions"
    url="~/CustomButtons/Default.aspx">
    <siteMapNode
        title="Using ButtonFields and Buttons in Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons as ButtonFields or within templates."
        url="~/CustomButtons/CustomButtons.aspx" />
</siteMapNode>

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

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

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

步骤 2:添加列出供应商的 FormView

让我们通过添加列出供应商的 FormView 开始使用本教程。 如“简介”中所述,此 FormView 将允许用户浏览供应商,并在 GridView 中显示供应商提供的产品。 此外,此 FormView 将包含一个按钮,单击时,会将所有供应商的产品标记为已停止。 在关注将自定义按钮添加到 FormView 之前,让我们先创建 FormView,以便显示供应商信息。

首先打开 CustomButtons.aspx 文件夹中的页面 CustomButtons 。 通过将窗体视图从工具箱拖动到设计器,并将其 ID 属性设置为 Suppliers。 从 FormView 智能标记中,选择创建名为 SuppliersDataSource 的新 ObjectDataSource。

创建名为 SuppliersDataSource 的新 ObjectDataSource

图 5:创建名为 SuppliersDataSource 的新 ObjectDataSource (单击可查看全尺寸图像

配置这一新的 ObjectDataSource,使其从 SuppliersBLL 类方法 GetSuppliers() 进行查询(请参阅图 6)。 由于此 FormView 不提供用于更新供应商信息的接口,因此从“更新”选项卡中的下拉列表中选择“无”选项。

将数据源配置为使用 SuppliersBLL 类的 GetSuppliers() 方法

图 6:将数据源配置为使用 SuppliersBLL 类方法 GetSuppliers()单击以查看全尺寸图像

配置 ObjectDataSource 后,Visual Studio 将生成 FormView InsertItemTemplateEditItemTemplateItemTemplate FormView。 InsertItemTemplate删除并EditItemTemplate修改ItemTemplate,使其仅显示供应商的公司名称和电话号码。 最后,通过选中其智能标记中的“启用分页”复选框(或通过将其 AllowPaging 属性设置为 True)来启用对 FormView 的分页支持。 在这些更改后,页面的声明性标记应如下所示:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False" AllowPaging="True">
    <ItemTemplate>
        <h3>
            <asp:Label ID="CompanyName" runat="server"
                Text='<%# Bind("CompanyName") %>' />
        </h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

图 7 显示通过浏览器查看时CustomButtons.aspx页。

FormView 列出当前所选供应商中的 CompanyName 和电话字段

图 7:FormView 列出 CompanyName 当前所选供应商中的字段 Phone单击以查看全尺寸图像

步骤 3:添加列出所选供应商产品的 GridView

在将“停用所有产品”按钮添加到 FormView 模板之前,让我们先在 FormView 下面添加一个 GridView,其中列出了所选供应商提供的产品。 为此,请将 GridView 添加到页面,将其 ID 属性 SuppliersProducts设置为 ,并添加名为 SuppliersProductsDataSource 的新 ObjectDataSource。

创建名为 SuppliersProductsDataSource 的新 ObjectDataSource

图 8:创建名为 SuppliersProductsDataSource 的新 ObjectDataSource (单击可查看全尺寸图像

将此 ObjectDataSource 配置为使用 ProductsBLL 类的方法 GetProductsBySupplierID(supplierID) (请参阅图 9)。 虽然此 GridView 允许调整产品的价格,但它不会使用内置编辑或删除 GridView 中的功能。 因此,我们可以将 ObjectDataSource 的 UPDATE、INSERT 和 DELETE 选项卡的下拉列表设置为“无”。

将数据源配置为使用 ProductsBLL 类 s GetProductsBySupplierID(supplierID) 方法

图 9:将数据源配置为使用 ProductsBLL 类方法 GetProductsBySupplierID(supplierID)单击以查看全尺寸图像

GetProductsBySupplierID(supplierID)由于该方法接受输入参数,ObjectDataSource 向导会提示我们输入此参数值的源。 若要从 FormView 传入 SupplierID 值,请将参数源下拉列表设置为 Control,并将 ControlID 下拉列表设置为 Suppliers (步骤 2 中创建的 FormView 的 ID)。

指示 supplierID 参数应来自供应商 FormView 控件

图 10:指示 supplierID 参数应来自 Suppliers FormView 控件(单击以查看全尺寸图像

完成 ObjectDataSource 向导后,GridView 将包含每个产品数据字段的 BoundField 或 CheckBoxField。 让我们向下剪裁一下,以便仅ProductNameUnitPrice显示与 CheckBoxField 一起Discontinued的 BoundField;此外,让我们设置 BoundField 的格式UnitPrice,使其文本的格式设置为货币。 GridView 和 SuppliersProductsDataSource ObjectDataSource 的声明性标记应类似于以下标记:

<asp:GridView ID="SuppliersProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="Suppliers" Name="supplierID"
            PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

此时,我们的教程显示主/详细信息报表,允许用户从顶部的 FormView 中选择供应商,并通过底部的 GridView 查看该供应商提供的产品。 图 11 显示了从 FormView 中选择东京交易员供应商时此页面的屏幕截图。

所选供应商的产品显示在 GridView 中

图 11:所选供应商的产品显示在 GridView 中(单击以查看全尺寸图像

步骤 4:创建 DAL 和 BLL 方法以停止供应商的所有产品

在向 FormView 添加按钮之前,单击该按钮会停止所有供应商的产品,首先需要向执行此操作的 DAL 和 BLL 添加方法。 具体而言,此方法将命名 DiscontinueAllProductsForSupplier(supplierID)。 单击 FormView 按钮时,我们将在业务逻辑层中调用此方法,并传入所选供应商; SupplierID然后 BLL 将调用相应的数据访问层方法,该方法将向停止指定供应商产品的数据库发出 UPDATE 声明。

正如我们在前面的教程中所做的那样,我们将使用自下而上的方法,从创建 DAL 方法开始,然后创建 BLL 方法,最后在 ASP.NET 页中实现该功能。 打开 Northwind.xsd 文件夹中的类型化数据集 App_Code/DAL ,并将新方法添加到 ProductsTableAdapter (右键单击 ProductsTableAdapter 并选择“添加查询”)。 这样做将启动 TableAdapter 查询配置向导,该向导将引导我们完成添加新方法的过程。 首先指示 DAL 方法将使用即席 SQL 语句。

使用即席 SQL 语句创建 DAL 方法

图 12:使用即席 SQL 语句创建 DAL 方法(单击以查看全尺寸图像

接下来,向导会提示我们创建哪种类型的查询。 DiscontinueAllProductsForSupplier(supplierID)由于该方法需要更新Products数据库表,因此Discontinued需要为指定supplierID提供的所有产品将字段设置为 1,因此我们需要创建更新数据的查询。

选择 UPDATE 查询类型

图 13:选择 UPDATE 查询类型(单击以查看全尺寸图像

下一个向导屏幕提供 TableAdapter 的现有 UPDATE 语句,用于更新 DataTable 中 Products 定义的每个字段。 将此查询文本替换为以下语句:

UPDATE [Products] SET
   Discontinued = 1
WHERE SupplierID = @SupplierID

输入此查询并单击“下一步”后,最后一个向导屏幕会要求使用 DiscontinueAllProductsForSupplier新方法的名称。 单击“完成”按钮完成向导。 返回到数据集设计器后,应会在命名DiscontinueAllProductsForSupplier(@SupplierID)ProductsTableAdapter看到一个新方法。

将新的 DAL 方法命名为 DiscontinueAllProductsForSupplier

图 14:命名新的 DAL 方法 DiscontinueAllProductsForSupplier单击以查看全尺寸图像

DiscontinueAllProductsForSupplier(supplierID)在数据访问层中创建的方法后,下一个任务是在业务逻辑层中创建DiscontinueAllProductsForSupplier(supplierID)该方法。 为此,请打开 ProductsBLL 类文件并添加以下内容:

Public Function DiscontinueAllProductsForSupplier(supplierID As Integer) As Integer
    Return Adapter.DiscontinueAllProductsForSupplier(supplierID)
End Function

此方法只调用 DiscontinueAllProductsForSupplier(supplierID) DAL 中的方法,并传递提供 supplierID 的参数值。 如果有任何业务规则只允许供应商的产品在某些情况下停止使用,则应在 BLL 中在此处实施这些规则。

注意

UpdateProduct与类中的ProductsBLL重载不同,DiscontinueAllProductsForSupplier(supplierID)方法签名不包括DataObjectMethodAttribute属性(<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, Boolean)>)。 这排除 DiscontinueAllProductsForSupplier(supplierID) 了“UPDATE”选项卡中 ObjectDataSource s“配置数据源向导”下拉列表中的方法。我省略了此属性,因为我们将直接从 ASP.NET 页中的事件处理程序调用 DiscontinueAllProductsForSupplier(supplierID) 该方法。

步骤 5:向 FormView 添加“停止使用所有产品”按钮

DiscontinueAllProductsForSupplier(supplierID)在 BLL 和 DAL 中完成方法后,添加停止所选供应商的所有产品的功能的最后一步是向 FormView s ItemTemplate添加 Button Web 控件。 让我们在供应商的电话号码下面添加这样的按钮,按钮文本为“停止所有产品”,属性值为 <a0ID/>。 可以通过设计器添加此按钮 Web 控件,方法是单击 FormView 智能标记中的“编辑模板”链接(请参阅图 15),或通过声明性语法直接添加。

将“停用所有产品”按钮 Web 控件添加到 FormView s ItemTemplate

图 15:向 FormView ItemTemplate 添加“停止使用所有产品”按钮 Web 控件(单击以查看全尺寸图像

当用户访问页面时单击该按钮,随后会触发回发并触发 FormView 事件ItemCommand。 若要执行自定义代码以响应单击的此按钮,我们可以为此事件创建事件处理程序。 但是,ItemCommand了解每当在 FormView 中单击任何 Button、LinkButton 或 ImageButton Web 控件时,该事件将触发。 这意味着,当用户在 FormView 中从一个页面移动到另一个页面时, ItemCommand 该事件将触发;当用户在支持插入、更新或删除的 FormView 中单击“新建”、“编辑”或删除时,会触发相同的操作。

ItemCommand由于无论单击了哪个按钮,都会触发,因此,在事件处理程序中,我们需要一种方法来确定是否单击了“停止所有产品”按钮,或者是否是其他按钮。 为此,我们可以将 Button Web 控件的属性 CommandName 设置为一些标识值。 单击“按钮”后, CommandName 此值将传递到 ItemCommand 事件处理程序中,使我们能够确定是否单击了“停止所有产品”按钮。 将“停止使用所有产品”按钮 CommandName 属性设置为“停止生产”。

最后,让我们使用客户端确认对话框来确保用户真正想要停止所选供应商的产品。 正如我们在“删除时添加客户端确认”教程中看到的那样,这可以通过一些 JavaScript 来完成。 具体而言,将 Button Web 控件的 OnClientClick 属性设置为 return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');

进行这些更改后,FormView 的声明性语法应如下所示:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False"
    AllowPaging="True">
    <ItemTemplate>
        <h3><asp:Label ID="CompanyName" runat="server"
            Text='<%# Bind("CompanyName") %>'></asp:Label></h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
        <br />
        <asp:Button ID="DiscontinueAllProductsForSupplier" runat="server"
            CommandName="DiscontinueProducts" Text="Discontinue All Products"
            OnClientClick="return confirm('This will mark _all_ of this supplier\'s
                products as discontinued. Are you certain you want to do this?');" />
    </ItemTemplate>
</asp:FormView>

接下来,为 FormView 事件 ItemCommand 创建事件处理程序。 在此事件处理程序中,我们需要首先确定是否单击“停止所有产品”按钮。 如果是这样,我们希望创建类的 ProductsBLL 实例并调用其 DiscontinueAllProductsForSupplier(supplierID) 方法,并传入 SupplierID 所选 FormView:

Protected Sub Suppliers_ItemCommand(sender As Object, e As FormViewCommandEventArgs) _
    Handles Suppliers.ItemCommand
    If e.CommandName.CompareTo("DiscontinueProducts") = 0 Then
        ' The "Discontinue All Products" Button was clicked.
        ' Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
        ' First, get the SupplierID selected in the FormView
        Dim supplierID As Integer = CType(Suppliers.SelectedValue, Integer)
        ' Next, create an instance of the ProductsBLL class
        Dim productInfo As New ProductsBLL()
        ' Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
        productInfo.DiscontinueAllProductsForSupplier(supplierID)
    End If
End Sub

请注意,SupplierID可以使用 FormView 属性SelectedValue访问 FormView 中当前选定的供应商。 该 SelectedValue 属性返回在 FormView 中显示的记录的第一个数据键值。 FormView s DataKeyNames 属性指示从中提取数据键值的数据字段,在步骤 2 中将 ObjectDataSource 绑定到 FormView 时,Visual Studio 会自动设置为 SupplierID 该字段。

创建事件处理程序后 ItemCommand ,花点时间测试页面。 浏览到Cocoiva de Quesos 'Las Cabras'供应商(它是 FormView 中第五个供应商)。 此供应商提供两种产品:Queso Cabrales 和 Queso Manchego La Pastora,这 两种产品均未 停产。

假设Cocoiva de Quesos 'Las Cabras'已经停业,因此其产品将被停产。 单击“停止使用所有产品”按钮。 这将显示客户端确认对话框(请参阅图 16)。

Coiva de Quesos Las Cabras 提供两种活动产品

图 16:Coiva de Quesos Las Cabras 提供两种活动产品(单击查看全尺寸图像

如果在客户端确认对话框中单击“确定”,表单提交将继续进行,导致 FormView 事件 ItemCommand 触发回发。 然后,我们创建的事件处理程序将执行,调用 DiscontinueAllProductsForSupplier(supplierID) 该方法并停止使用 Queso Cabrales 和 Queso Manchego La Pastora 产品。

如果已禁用 GridView 视图状态,则 GridView 将在每次回发时反弹到基础数据存储,因此将立即更新以反映这两种产品现已停用(见图 17)。 但是,如果在 GridView 中未禁用视图状态,则进行此更改后,需要手动将数据重新绑定到 GridView。 为此,只需在调用DiscontinueAllProductsForSupplier(supplierID)该方法后立即调用 GridView 方法DataBind()即可。

单击“停止使用所有产品”按钮后,供应商的产品会相应地更新

图 17:单击“停止使用所有产品”按钮后,供应商的产品将相应地更新(单击以查看全尺寸图像

步骤 6:在业务逻辑层中创建 UpdateProduct 重载以调整产品价格

与 FormView 中的“停止使用所有产品”按钮一样,若要添加用于在 GridView 中增加和降低产品价格的按钮,首先需要添加适当的数据访问层和业务逻辑层方法。 由于我们已经有一个在 DAL 中更新单个产品行的方法,因此可以通过在 BLL 中为 UpdateProduct 该方法创建新的重载来提供此类功能。

我们过去的 UpdateProduct 重载采用产品字段作为标量输入值的一些组合,然后只更新指定产品的这些字段。 对于此重载,我们将与此标准略有不同,而是传入产品和 ProductID 调整 UnitPrice 的百分比(而不是传入新的,调整 UnitPrice 本身)。 此方法将简化我们需要在 ASP.NET 页代码隐藏类中编写的代码,因为我们不必费心确定当前产品 UnitPrice

本教程的 UpdateProduct 重载如下所示:

Public Function UpdateProduct _
    (unitPriceAdjustmentPercentage As Decimal, productID As Integer) As Boolean
    Dim products As Northwind.ProductsDataTable = Adapter.GetProductByProductID(productID)
    If products.Count = 0 Then
        ' no matching record found, return false
        Return False
    End If
    Dim product As Northwind.ProductsRow = products(0)
    ' Adjust the UnitPrice by the specified percentage (if it's not NULL)
    If Not product.IsUnitPriceNull() Then
        product.UnitPrice *= unitPriceAdjustmentPercentage
    End If
    ' Update the product record
    Dim rowsAffected As Integer = Adapter.Update(product)
    ' Return true if precisely one row was updated, otherwise false
    Return rowsAffected = 1
End Function

此重载通过 DAL 方法 GetProductByProductID(productID) 检索有关指定产品的信息。 然后,它会检查产品 UnitPrice 是否分配了数据库 NULL 值。 如果是,价格保持不变。 但是,如果存在非NULLUnitPrice值,则该方法按指定的百分比(unitPriceAdjustmentPercent)更新产品UnitPrice

步骤 7:向 GridView 添加增加和减少按钮

GridView (和 DetailsView)均由字段集合组成。 除了 BoundFields、CheckBoxFields 和 TemplateFields 之外,ASP.NET 还包括 ButtonField(顾名思义),它以按钮、LinkButton 或 ImageButton 呈现为每行的列。 与 FormView 类似,单击 GridView 分页按钮、编辑或删除按钮、排序按钮等中的任何按钮会导致回发并引发 GridView 事件RowCommand

ButtonField 具有一个 CommandName 属性,该属性将指定值分配给其每个 Buttons CommandName 属性。 与 FormView 一样, CommandName 事件处理程序使用 RowCommand 该值来确定单击了哪个按钮。

让我们将两个新的 ButtonFields 添加到 GridView,一个是按钮文本 Price +10%,另一个是文本 Price -10%。 若要添加这些 ButtonField,请单击 GridView 智能标记中的“编辑列”链接,从左上角列表中选择 ButtonField 字段类型,然后单击“添加”按钮。

将两个 ButtonFields 添加到 GridView

图 18:向 GridView 添加两个 ButtonFields

移动两个 ButtonField,以便它们显示为前两个 GridView 字段。 接下来,将 Text 这两个 ButtonField 的属性分别设置为 Price +10% 和 Price -10%,并将 CommandName 属性分别设置为 IncreasePrice 和 DecreasePrice。 默认情况下,ButtonField 将其按钮列呈现为 LinkButtons。 但是,可以通过 ButtonField s ButtonType 属性更改此设置。 让我们让这两个 ButtonField 呈现为常规按下按钮;因此,将 ButtonType 属性设置为 Button. 图 19 显示了这些更改后的“字段”对话框;下面是 GridView 的声明性标记。

配置 ButtonFields Text、CommandName 和 ButtonType 属性

图 19:配置 ButtonFields TextCommandNameButtonType属性

<asp:GridView ID="SuppliersProducts" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:ButtonField ButtonType="Button" CommandName="IncreasePrice"
            Text="Price +10%" />
        <asp:ButtonField ButtonType="Button" CommandName="DecreasePrice"
            Text="Price -10%" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

创建这些 ButtonFields 后,最后一步是为 GridView 事件 RowCommand 创建事件处理程序。 如果由于单击了 Price +10% 或 Price -10% 按钮而触发此事件处理程序,则需要确定ProductID单击其按钮的行,然后调用ProductsBLL类的方法UpdateProduct,并传递相应的UnitPrice百分比调整以及ProductID 以下代码执行以下任务:

Protected Sub SuppliersProducts_RowCommand _
    (sender As Object, e As GridViewCommandEventArgs) _
        Handles SuppliersProducts.RowCommand
    If e.CommandName.CompareTo("IncreasePrice") = 0 OrElse _
       e.CommandName.CompareTo("DecreasePrice") = 0 Then
        ' The Increase Price or Decrease Price Button has been clicked
        ' Determine the ID of the product whose price was adjusted
        Dim productID As Integer = Convert.ToInt32( _
            SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)
        ' Determine how much to adjust the price
        Dim percentageAdjust As Decimal
        If e.CommandName.CompareTo("IncreasePrice") = 0 Then
            percentageAdjust = 1.1
        Else
            percentageAdjust = 0.9
        End If
        ' Adjust the price
        Dim productInfo As New ProductsBLL()
        productInfo.UpdateProduct(percentageAdjust, productID)
    End If
End Sub

若要确定 ProductID 单击了 Price +10% 或 Price -10% 按钮的行,我们需要咨询 GridView 集合 DataKeys 。 此集合保存每个 GridView 行的属性中指定的 DataKeyNames 字段的值。 由于将 ObjectDataSource 绑定到 GridView 时 Visual Studio 将 GridView 的属性 DataKeyNames 设置为 ProductID, DataKeys(rowIndex).ValueProductID 提供指定的 rowIndex

ButtonField 会自动传入其按钮通过e.CommandArgument参数单击的行的 rowIndex。 因此,若要确定ProductID单击其 Price +10% 或 Price -10% 按钮的行,我们将使用: Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)

与“停用所有产品”按钮一样,如果已禁用 GridView 视图状态,则 GridView 将在每次回发时反弹到基础数据存储,因此将立即更新,以反映单击任一按钮时发生的价格更改。 但是,如果在 GridView 中未禁用视图状态,则进行此更改后,需要手动将数据重新绑定到 GridView。 为此,只需在调用UpdateProduct该方法后立即调用 GridView 方法DataBind()即可。

图 20 显示查看奶奶凯利家园提供的产品时的页面。 图 21 显示了在“价格 +10%”按钮被单击两次后的结果,奶奶的“男孩莓传播”和“价格-10%”按钮一次用于诺思伍德·克兰贝里酱。

GridView 包括价格 +10% 和价格 -10% 按钮

图 20:GridView 包括价格 +10% 和价格 -10% 按钮(单击以查看全尺寸图像

第一个和第三个产品的价格已通过价格 +10% 和价格 -10% 按钮更新

图 21:第一个和第三个产品的价格已通过价格 +10% 和价格 -10% 按钮更新(单击以查看全尺寸图像

注意

GridView(和 DetailsView)还可以将 Buttons、LinkButtons 或 ImageButtons 添加到其 TemplateFields。 与 BoundField 一样,单击后,这些按钮将引发回发,引发 GridView 事件 RowCommand 。 但是,在 TemplateField 中添加按钮时,Button s CommandArgument 不会自动设置为行的索引,就像使用 ButtonFields 时一样。 如果需要确定在事件处理程序中 RowCommand 单击的按钮的行索引,则需要使用如下代码在 TemplateField 中的声明性语法中手动设置 Button 属性 CommandArgument
<asp:Button runat="server" ... CommandArgument='<%# CType(Container, GridViewRow).RowIndex %>' />

总结

GridView、DetailsView 和 FormView 控件都可以包括 Buttons、LinkButtons 或 ImageButtons。 单击后,此类按钮会导致回发,并在 FormView 和 DetailsView 控件中引发 ItemCommand 事件,以及 RowCommand GridView 中的事件。 这些数据 Web 控件具有内置功能来处理与命令相关的常见操作,例如删除或编辑记录。 但是,还可以使用按钮,单击时,通过执行自己的自定义代码做出响应。

为此,我们需要为 ItemCommandRowCommand 事件创建事件处理程序。 在此事件处理程序中,我们首先检查传入 CommandName 值以确定单击了哪个按钮,然后执行适当的自定义操作。 本教程介绍了如何使用按钮和 ButtonFields 停止指定供应商的所有产品,或者将特定产品的价格提高或降低 10%。

快乐编程!

关于作者

斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0。 他可以通过他的博客联系到mitchell@4GuysFromRolla.com他,可以在该博客中找到http://ScottOnWriting.NET