共用方式為


新增與回應 GridView 的按鈕 (VB)

作者 :Scott Mitchell

下載 PDF

在本教學課程中,我們將探討如何將自定義按鈕新增至範本和 GridView 或 DetailsView 控件的欄位。 特別是,我們將建置具有 FormView 的介面,可讓使用者逐頁流覽供應商。

簡介

雖然許多報告案例牽涉到對報表數據的唯讀存取,但報表並不常見,包括根據顯示的數據執行動作的能力。 這通常牽涉到新增 Button、LinkButton 或 ImageButton Web 控制件,並在報表中顯示每個記錄時按兩下時,造成回傳並叫用某些伺服器端程式代碼。 以記錄為基礎編輯和刪除資料是最常見的範例。 事實上,如同我們從 插入、更新和刪除數據 概觀開始所見,編輯和刪除教學課程很常見,因此 GridView、DetailsView 和 FormView 控件可以支援這類功能,而不需要撰寫單行程式代碼。

除了 [編輯] 和 [刪除] 按鈕之外,GridView、DetailsView 和 FormView 控件也可以包含 Buttons、LinkButtons 或 ImageButtons,在單擊時,執行一些自定義伺服器端邏輯。 在本教學課程中,我們將探討如何將自定義按鈕新增至範本和 GridView 或 DetailsView 控件的欄位。 特別是,我們將建置具有 FormView 的介面,可讓使用者逐頁流覽供應商。 針對指定的供應商,FormView 會顯示供應商的相關資訊以及按鈕 Web 控制件,如果按一下,則會將其所有相關聯的產品標示為已停止。 此外,GridView 會列出所選供應商所提供的產品,其中每一個數據列都包含 [增加價格] 和 [折扣價格] 按鈕,如果按兩下,則會將產品 UnitPrice 提高或減少為 10%, (請參閱圖 1) 。

FormView 和 GridView 都包含執行自定義動作的按鈕

圖 1:FormView 和 GridView 包含執行自定義動作的按鈕, (按兩下即可檢視完整大小的影像)

步驟 1:新增按鈕教學課程網頁

在查看如何新增自定義按鈕之前,讓我們先花點時間在網站專案中建立 ASP.NET 頁面,我們將在本教學課程中需要。 首先,新增名為 CustomButtons的新資料夾。 接下來,將下列兩個 ASP.NET 頁面新增至該資料夾,請務必讓每個頁面與主版頁面產生 Site.master 關聯:

  • Default.aspx
  • CustomButtons.aspx

新增自定義 Buttons-Related 教學課程的 ASP.NET 頁面

圖 2:新增自定義 Buttons-Related 教學課程的 ASP.NET 頁面

就像在其他資料夾中一樣, Default.aspx 資料夾中 CustomButtons 的 將會列出其區段中的教學課程。 回想一下, SectionLevelTutorialListing.ascx 使用者控件會提供這項功能。 因此,將這個使用者控制件Default.aspx從 方案總管 拖曳至頁面的設計檢視,將它新增至 。

將 SectionLevelTutorialListing.ascx 使用者控件新增至 Default.aspx

圖 3:新增 SectionLevelTutorialListing.ascx 使用者控件以 Default.aspx (按兩下以檢視完整大小的影像)

最後,將頁面新增為檔案的專案 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 開始。 將 FormView 從 [工具箱] 拖曳至頁面,將它拖曳至 Designer,並將其 屬性設定IDSuppliers。 從 FormView 智慧標記中,選擇建立名為 SuppliersDataSource的新 ObjectDataSource。

建立名為 SuppliersDataSource 的新 ObjectDataSource

圖 5:建立名為 SuppliersDataSource 的新 ObjectDataSource (按兩下即可檢視完整大小的影像)

設定這個新的 ObjectDataSource,使其從 SuppliersBLL 類別 s GetSuppliers() 方法查詢 (請參閱圖 6) 。 由於此 FormView 不提供更新供應商資訊的介面,因此請從 [更新] 索引標籤的下拉式清單中選取 ([無) ] 選項。

將數據源設定為使用 SuppliersBLL 類別的 GetSuppliers () 方法

圖 6:將數據源設定為使用 SuppliersBLL 類別 s GetSuppliers() 方法 (按鍵即可檢視完整大小的影像)

設定 ObjectDataSource 之後,Visual Studio 會為 FormView 產生 InsertItemTemplateEditItemTemplateItemTemplateInsertItemTemplate拿掉和 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 s UPDATE、INSERT 和 DELETE 索引標籤,將下拉式清單設定為 ([無]) 。

將數據源設定為使用 ProductsBLL 類別 s GetProductsBySupplierID (supplierID) 方法

圖 9:將數據源設定為使用 ProductsBLL 類別 s GetProductsBySupplierID(supplierID) 方法, (按兩下即可檢視完整大小的影像)

GetProductsBySupplierID(supplierID)因為 方法接受輸入參數,所以 ObjectDataSource 精靈會提示我們輸入此參數值的來源。 若要從 FormView 傳入 SupplierID 值,請將 [參數來源] 下拉式清單設定為 Control,並將 ControlID 下拉式清單設定為 Suppliers (步驟 2) 中所建立的 FormView 識別符。

指出 supplierID 參數應來自供應商 FormView 控件

圖 10:指出 supplierID 參數應該來自 Suppliers FormView 控件, (按兩下即可檢視完整大小的影像)

完成 ObjectDataSource 精靈之後,GridView 將會包含每個產品數據欄位的 BoundField 或 CheckBoxField。 讓我們向下修剪,只 ProductName 顯示 和 UnitPrice BoundField Discontinued 與 CheckBoxField;此外,讓我們格式化 UnitPrice BoundField,使其文字格式化為貨幣。 您的 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 選取東京 Traders 供應商時,此頁面的螢幕快照。

選取的供應商產品會顯示在 GridView 中

圖 11:選取的供應商產品會顯示在 GridView 中, (按兩下即可檢視完整大小的影像)

步驟 4:建立 DAL 和 BLL 方法以停止供應商的所有產品

在我們可以將 Button 新增至 FormView 之前,按兩下時停止所有供應商的產品,我們必須先將方法新增至執行此動作的 DAL 和 BLL。 特別是,這個方法會命名為 DiscontinueAllProductsForSupplier(supplierID)。 按兩下 FormView 的按鈕時,我們會在商業規則層中叫用這個方法,並傳入選取的供應商 ;BLL 接著會呼叫對應的數據存取層方法,這會對停止指定供應商 SupplierID產品的資料庫發出 UPDATE 語句。

如同我們在先前的教學課程中所做的一樣,我們將使用由下而下的方法,從建立 DAL 方法、BLL 方法開始,最後在 [ASP.NET] 頁面中實作功能。 Northwind.xsd開啟 資料夾中的 [具類型數據集App_Code/DAL],然後將新的方法新增至 ProductsTableAdapter (以滑鼠右鍵按兩下 ,ProductsTableAdapter然後選擇 [新增查詢) ]。 這麼做將會啟動 TableAdapter 查詢設定精靈,以逐步引導我們完成新增方法的程式。 首先,指出 DAL 方法會使用臨機操作 SQL 語句。

使用臨機操作 SQL 語句建立 DAL 方法

圖 12:使用臨機操作 SQL 語句建立 DAL 方法, (按兩下即可檢視完整大小的影像)

接下來,精靈會提示我們輸入要建立的查詢類型。 DiscontinueAllProductsForSupplier(supplierID)因為方法需要更新Products資料庫數據表,所以針對指定 supplierID提供的所有產品,Discontinued將字段設定為1,我們需要建立更新數據的查詢。

選擇 [更新查詢類型]

圖 13:選擇 [更新查詢類型] (按兩下即可檢視完整大小的映像)

下一個精靈畫面會提供 TableAdapter 的現有 UPDATE 語句,以更新 DataTable 中 Products 定義的每個欄位。 以下欄語句取代此查詢文字:

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

輸入此查詢並按兩下一步之後,最後一個精靈畫面會要求使用新的方法名稱 DiscontinueAllProductsForSupplier。 按兩下 [完成] 按鈕以完成精靈。 返回 DataSet Designer 您應該會在名為 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 中完成 方法之後,新增終止所選供貨商所有產品的能力的最後一個步驟是將 Button Web 控件新增至 FormView s ItemTemplate。 讓我們在供應商電話號碼下方新增這類按鈕,其中包含按鈕文字[停止所有產品] 和 ID 屬性值 DiscontinueAllProductsForSupplier。 您可以按下 FormView 智慧標記中的 [編輯範本] 連結,以透過 Designer 新增此 Button Web 控件, (請參閱圖 15) ,或直接透過宣告式語法。

將 [停止所有產品] 按鈕 Web 控件新增至 FormView s ItemTemplate

圖 15:將 [停止所有產品] 按鈕 Web 控件新增至 FormView s ItemTemplate (按兩下即可檢視完整大小的影像)

當使用者瀏覽頁面時按兩下Button,就會引發回傳並引發 FormView 事件ItemCommand。 若要執行自定義程式代碼以回應按下的這個 Button,我們可以為此事件建立事件處理程式。 不過,瞭解 ItemCommand 每當在 FormView 內按兩下 任何 Button、LinkButton 或 ImageButton Web 控制件時,就會引發事件。 這表示當使用者從 FormView 中的一個頁面移到另一個頁面時,就會 ItemCommand 引發事件;當使用者在支援插入、更新或刪除的 FormView 中按兩下 [新增]、[編輯] 或 [刪除] 時,就會發生相同的動作。

ItemCommand由於 無論按下哪個按鈕,都會引發 ,因此在事件處理程式中,我們需要一種方式來判斷是否按下 [停止所有產品] 按鈕,或是否為其他按鈕。 為了達成此目的,我們可以將 Button Web 控件的 CommandName 屬性設定為一些識別值。 按兩下 [按鈕] 時,這個 CommandName 值會傳遞至 ItemCommand 事件處理程式,讓我們判斷是否按兩下 [停止所有產品] 按鈕。 將 [停止所有產品] 按鈕的 CommandName 屬性設定為 DiscontinueProducts 。

最後,讓我們使用用戶端確認對話方塊,以確保使用者真的想要停止選取的供應商產品。 如我們在 刪除時新增 Client-Side 確認 教學課程中所見,這可以使用一些 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 的 屬性來存取 FormView 中目前選取供應商的 SelectedValue。 屬性 SelectedValue 會傳回 FormView 中所顯示記錄的第一個數據索引鍵值。 FormView 的 DataKeyNames 屬性會指出從中提取數據索引鍵值的數據欄位,在將 ObjectDataSource 系結回步驟 2 時,Visual Studio 會自動設定為 SupplierID

建立事件處理程式后 ItemCommand ,請花點時間測試頁面。 流覽至 (為 FormView for) me 中的第五個供應商,請流覽至[Quesos 'Las Cabras' 供貨商]。 此供應商提供兩項產品:Queso Cabrales 和 Queso Manchego La Pastora,這兩項 都未 中止。

想像一下,其產品已停止運作,因此已停止其產品。 按兩下 [停止所有產品] 按鈕。 這會顯示用戶端確認對話框, (請參閱圖 16) 。

在 Quesos Las Cabras 提供兩個作用中產品

圖 16: (按兩下即可檢視完整大小的影像)

如果您在用戶端確認對話框中按兩下 [確定],表單提交將會繼續,導致會引發 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 s GetProductByProductID(productID) 方法擷取指定產品的相關信息。 然後,它會檢查產品 UnitPrice 是否已指派資料庫 NULL 值。 如果是,價格會保持不變。 不過,如果有非NULLUnitPrice 值,方法會依指定的百分比更新產品 UnitPrice , (unitPriceAdjustmentPercent) 。

步驟 7:將 [增加] 和 [減少] 按鈕新增至 GridView

GridView (和 DetailsView) 都是由欄位集合所組成。 除了 BoundFields、CheckBoxFields 和 TemplateFields 之外,ASP.NET 還包含 ButtonField,如其名稱所示,會轉譯為每個數據列具有 Button、LinkButton 或 ImageButton 的數據行。 類似於 FormView,按下 GridView 分頁按鈕、編輯或刪除按鈕、排序按鈕等中的任何按鈕會導致回傳並引發 GridView 事件RowCommand

ButtonField 具有屬性 CommandName ,會將指定的值指派給其每個 Buttons CommandName 屬性。 就像 FormView 一樣, CommandName 事件處理程式會使用 RowCommand 此值來判斷按下哪一個按鈕。

讓我們將兩個新的 ButtonField 新增至 GridView,其中一個具有按鈕文字 Price +10%,另一個則包含文字 Price -10%。 若要新增這些 ButtonFields,請按下 GridView 智慧標記中的 [編輯資料行] 連結,從左上方的清單中選取 ButtonField 欄位類型,然後按兩下 [新增] 按鈕。

將兩個 ButtonFields 新增至 GridView

圖 18:將兩個 ButtonField 新增至 GridView

移動兩個 ButtonFields,使其顯示為前兩個 GridView 字段。 接下來,將這兩個 ButtonFields 的屬性分別設定 Text 為 Price +10% 和 Price -10%,並將 CommandName 屬性分別設定為 IncreasePrice 和 DecreasePrice。 根據預設,ButtonField 會將其按鈕數據行轉譯為LinkButtons。 不過,這可以透過 ButtonField 的 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 用 類別 s 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).Value為指定的 rowIndex 提供 ProductID

ButtonField 會自動傳入透過 參數按鍵e.CommandArgument之數據列的 rowIndex。 因此,若要判斷 ProductID 按下 [價格 + 10%] 或 [價格 -10%] 按鈕之數據列的 ,我們會使用: Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)

如同 [停止所有產品] 按鈕,如果您已停用 GridView 的檢視狀態,GridView 會在每個回傳時重新系結至基礎數據存放區,因此會立即更新,以反映從按兩下任一按鈕所發生的價格變更。 不過,如果您尚未在 GridView 中停用檢視狀態,在進行這項變更之後,您必須手動將數據重新繫結至 GridView。 若要達成此目的,只要在叫UpdateProduct用 方法之後立即呼叫 GridView 方法DataBind()即可。

圖 20 顯示檢視 Grandma Kelly 所提供之家用版產品時的頁面。 圖 21 顯示在 [價格 + 10%] 按鈕已針對 Grandma's Sauceenberry Spread 按兩次後的結果,而 Northwoods Cranberry Sauce 的 [價格] -10% 按鈕一次。

GridView 包含價格 +10% 和價格 -10% 按鈕

圖 20:GridView 包含價格 +10% 和價格 -10% 按鈕, (按兩下即可檢視完整大小的影像)

第一個和第三項產品的價格已透過價格 +10% 和價格 -10% 按鈕更新

圖 21:第一個和第三項產品的價格已透過價格 +10% 和價格 -10% 按鈕更新, (單擊以檢視大小完整的影像)

注意

GridView (和 DetailsView) 也可以將 Buttons、LinkButtons 或 ImageButtons 新增至其 TemplateFields。 如同 BoundField,按兩下時,這些 Buttons 會引發回傳,並引發 GridView s 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%。

快樂的程序設計!

關於作者

Scott Mitchell 是七份 ASP/ASP.NET 書籍的作者,以及 1998 年以來與 Microsoft Web 技術合作的 4GuysFromRolla.com 作者。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格來連線到 ,您可以在 找到http://ScottOnWriting.NET