共用方式為


新增 GridView 的核取方塊欄 (C#)

斯科特·米切爾

下載 PDF

本教學課程將探討如何將複選框數據行新增至 GridView 控件,為使用者提供選取 GridView 多個數據列的直覺方式。

簡介

在上述教學課程中,我們探討了如何為 GridView 新增單選按鈕欄,以便選取特定記錄。 單選按鈕列是適合的使用者介面,當使用者最多只能從網格中選擇一個項目時。 不過,有時候,我們可能想要允許使用者從方格中挑選任意數目的物品。 例如,Web 型電子郵件客戶程式通常會以複選框列顯示訊息清單。 用戶可以選取任意數目的郵件,然後執行一些動作,例如將電子郵件移至另一個資料夾或刪除它們。

在本教學課程中,我們將瞭解如何新增複選框欄,以及如何判斷回傳事件時選取的複選框。 特別是,我們將建置一個範例,以密切模擬 Web 型電子郵件用戶端用戶介面。 我們的範例會包含分頁方格檢視,其中列出資料庫數據表中的 Products 產品,每個數據列都有一個複選框(請參閱圖 1)。 按兩下 [刪除選取的產品] 按鈕將會刪除選取的產品。

每個產品數據列都包含複選框

圖 1:每個產品資料列都包含複選框(按兩下以檢視完整大小的影像

步驟 1:新增列出產品資訊的 Paged GridView

在考慮新增複選框欄位之前,我們先專注於在支援分頁功能的 GridView 中列出產品。 從CheckBoxField.aspx資料夾中的EnhancedGridView頁面開始,將 [工具箱] 中的 GridView 拖曳到設計工具,然後將其ID設定為Products。 接下來,選擇將 GridView 系結至名為 ProductsDataSource的新 ObjectDataSource。 將 ObjectDataSource 設定為使用 ProductsBLL 類別,呼叫 GetProducts() 方法來傳回數據。 由於此 GridView 將是唯讀的,因此請將 UPDATE、INSERT 和 DELETE 索引標籤標的下拉式清單設定為 [無]。

建立新的 ObjectDataSource,名為 ProductsDataSource

圖 2:建立名為 ProductsDataSource 的新 ObjectDataSource (按兩下以檢視完整大小的影像

使用 GetProducts() 方法設定 ObjectDataSource 以擷取數據

圖 3:使用 GetProducts() 方法設定 ObjectDataSource 擷取資料 (按兩下以檢視完整大小的影像

將 UPDATE、INSERT 和 DELETE 索引標籤中的 Drop-Down 清單設定為 [無]

圖 4:將 UPDATE、INSERT 和 DELETE 索引標籤標的 Drop-Down 列表設定為 [無] (按兩下以檢視完整大小的影像

完成 [設定數據源精靈] 之後,Visual Studio 會自動為產品相關數據欄位建立 BoundColumns 和 CheckBoxColumn。 如同我們在上一個教學課程中所做的,請移除除ProductNameCategoryNameUnitPrice BoundFields 之外的所有專案,並將HeaderText屬性變更為Product、Category和Price。 設定 UnitPrice BoundField,使其值格式化為貨幣。 也請從智慧標記中核取 [啟用分頁] 複選框,設定 GridView 以支援分頁。

讓我們新增使用者介面來刪除選取的產品。 在 GridView 底下新增 Button Web 控件,並將其 ID 設定為 DeleteSelectedProducts ,並將其 Text 屬性設定為 [刪除選取的產品]。 在此範例中,我們不會實際刪除資料庫中的產品,而是只會顯示一則訊息,指出已刪除的產品。 若要容納這種情況,請在 [按鈕] 底下新增標籤 Web 控件。 將識別碼設定為 DeleteResults、清除其 TextVisible 屬性,並將其與 EnableViewState 屬性設定為 false

進行這些變更之後,GridView、ObjectDataSource、Button 和 Label 宣告式標記應該類似下列內容:

<p>
    <asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
        AllowPaging="True" EnableViewState="False">
        <Columns>
            <asp:BoundField DataField="ProductName" HeaderText="Product" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                ReadOnly="True" SortExpression="CategoryName" />
            <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                HeaderText="Price" HtmlEncode="False" 
                SortExpression="UnitPrice" />
        </Columns>
    </asp:GridView>
    <asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}" 
        SelectMethod="GetProducts" TypeName="ProductsBLL">            
    </asp:ObjectDataSource>
</p>
<p>
    <asp:Button ID="DeleteSelectedProducts" runat="server" 
        Text="Delete Selected Products" />
</p>
<p>
    <asp:Label ID="DeleteResults" runat="server" EnableViewState="False" 
        Visible="False"></asp:Label>
</p>

花點時間在瀏覽器中檢視頁面(請參閱圖 5)。 此時,您應該會看到前十個產品的名稱、類別和價格。

列出前十個產品的名稱、類別和價格

圖 5:列出前十個產品的名稱、類別和價格(按兩下以檢視全尺寸影像

步驟 2:新增一欄複選框

由於 ASP.NET 2.0 包含 CheckBoxField,因此人們可能會認為它可以用來將複選框列新增至 GridView。 不幸的是,情況並非如此,因為 CheckBoxField 是設計來使用布爾數據欄位。 也就是說,若要使用 CheckBoxField,我們必須指定底層資料欄位,其值用來判斷被呈現的複選框是否被選取。 我們不能使用 CheckBoxField 來僅包含一列未勾選的核取框。

相反地,我們必須新增 TemplateField,並將 CheckBox Web 控制項新增至其 ItemTemplate。 繼續將 TemplateField 新增至 Products GridView,使其成為第一個 (極左) 字段。 從 GridView 的智慧標記中,按兩下 [編輯範本] 連結,然後將 CheckBox Web 控制件從 [工具箱] 拖曳至 ItemTemplate。 將此 CheckBox s ID 屬性設定為 ProductSelector

將名為 ProductSelector 的 CheckBox Web 控件新增至 TemplateField s ItemTemplate

圖 6:將名為 ProductSelector 的 CheckBox Web 控件新增至 TemplateField s ItemTemplate按兩下以檢視完整大小的影像

新增 TemplateField 和 CheckBox Web 控制件後,每個數據列現在都會包含複選框。 圖 7 顯示此頁面,在新增 TemplateField 和 CheckBox 之後,透過瀏覽器檢視時。

每個產品數據列現在都包含複選框

圖 7:每個產品資料列現在都包含複選框(按兩下以檢視完整大小的影像

步驟 3:判斷回傳時核取的複選框

此時,我們有一欄複選框,但無法判斷回傳時哪些複選框被核取。 不過,按兩下 [刪除選取的產品] 按鈕時,我們需要知道已核取哪些複選框,才能刪除這些產品。

GridView 的 Rows 屬性 可讓您存取 GridView 中的數據列。 我們可以逐一查看這些數據列、以程序設計方式存取 CheckBox 控件,然後查閱其 Checked 屬性以判斷 CheckBox 是否已選取。

建立 DeleteSelectedProducts Button Web 控制項的事件處理程式以處理 Click 事件,並添加以下程式代碼:

protected void DeleteSelectedProducts_Click(object sender, EventArgs e)
{
    bool atLeastOneRowDeleted = false;
    // Iterate through the Products.Rows property
    foreach (GridViewRow row in Products.Rows)
    {
        // Access the CheckBox
        CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
        if (cb != null && cb.Checked)
        {
            // Delete row! (Well, not really...)
            atLeastOneRowDeleted = true;
            // First, get the ProductID for the selected row
            int productID = 
                Convert.ToInt32(Products.DataKeys[row.RowIndex].Value);
            // "Delete" the row
            DeleteResults.Text += string.Format(
                "This would have deleted ProductID {0}<br />", productID);
        }
    }
    // Show the Label if at least one row was deleted...
    DeleteResults.Visible = atLeastOneRowDeleted;
}

屬性 Rows 會傳回構成 GridView 數據列的實例集合 GridViewRow 。 這裡的 foreach 迴圈會列舉這個集合。 針對每個 GridViewRow 物件,可以使用 row.FindControl("controlID") 程式化地存取該資料列的 CheckBox。 如果勾選核取方塊,則會從 ProductID 集合中擷取該列對應的 DataKeys 值。 在此練習中,我們只會在標籤中 DeleteResults 顯示一則資訊訊息,不過在工作應用程式中,我們會改為呼叫 ProductsBLL 類別 s DeleteProduct(productID) 方法。

在新增此事件處理常式後,按一下【刪除選取的產品】按鈕會顯示所選產品的 ProductID

按兩下 [刪除選取的產品] 按鈕時,會列出選取的產品產品標識碼

圖 8:點擊 [刪除選取的產品] 按鈕時,會列出 [選取的產品 ProductID ] (點擊檢視完整大小的影像

步驟 4: 新增「全選」和「取消全選」按鈕

如果使用者想要刪除目前頁面上的所有產品,他們必須核取十個複選框中的每一個。 我們可以新增一個 [全部核取] 按鈕,協助加速此過程,點擊時選取方格中的所有核取方塊。 新增一個取消全選按鈕將同樣有幫助。

將兩個 Button Web 控件新增至頁面,並將其放在 GridView 上方。 將第一個 設定為 ,IDCheckAll並將其 Text 屬性設定為 Check All ;將第二個設定為 ,IDUncheckAll並將其 Text 屬性設定為 Uncheck All 。

<asp:Button ID="CheckAll" runat="server" Text="Check All" />
 
<asp:Button ID="UncheckAll" runat="server" Text="Uncheck All" />

接下來,在名為 ToggleCheckState(checkState) 的程式代碼後置類別中建立方法,並在叫用時列舉 Products GridView 集合 Rows ,並將每個 CheckBox s Checked 屬性設定為 checkState 參數中傳遞的值。

private void ToggleCheckState(bool checkState)
{
    // Iterate through the Products.Rows property
    foreach (GridViewRow row in Products.Rows)
    {
        // Access the CheckBox
        CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
        if (cb != null)
            cb.Checked = checkState;
    }
}

接下來,建立 ClickCheckAllUncheckAll 按鈕的事件處理程式。 在 CheckAll 事件處理程式中,只要呼叫 ToggleCheckState(true);在 中 UncheckAll,呼叫 ToggleCheckState(false)

protected void CheckAll_Click(object sender, EventArgs e)
{
    ToggleCheckState(true);
}
protected void UncheckAll_Click(object sender, EventArgs e)
{
    ToggleCheckState(false);
}

使用此程式碼時,按一下 [全部選取] 按鈕會造成回傳,並選取 GridView 中的所有複選框。 同樣地,按一下 “取消全選” 可以取消選取所有複選框。 圖 9 顯示按下 [全部核取] 按鈕之後的螢幕畫面。

按一下 [全選按鈕] 選取所有核取方塊

圖 9:按兩下 [全部核取] 按鈕選取所有複選框(按兩下以檢視完整大小的影像

備註

顯示複選框數據行時,選取或取消選取所有複選框的其中一種方法是透過標頭數據列中的複選框。 此外,目前的 Check All /Uncheck All 實作需要回傳。 然而,您可以完全透過用戶端腳本來核取或取消核取複選框,藉此提供更流暢的用戶體驗。 若要詳細探索在標題列複選框中使用 [全部核取] 和 [取消全部核取],以及討論使用用戶端技術,請參閱 使用 Client-Side 腳本與 Check All CheckBox 檢查 GridView 中所有的複選框

總結

如果您需要讓使用者在繼續之前,先從 GridView 選擇任意數目的數據列,新增一欄複選框是一個選項。 如本教學課程中所見,在 GridView 中包括一欄的複選框,需要新增具有 CheckBox Web 控制項的 TemplateField。 藉由使用 Web 控制項(相較於直接將標記插入範本中,如同我們在上一個教學課程中所做的一樣),ASP.NET 會自動記住哪個多選框在回傳過程中已被選取或未被選取。 我們也可以以程式設計方式存取程序代碼中的 CheckBox,以判斷指定的 CheckBox 是否已核取,或變更核取的狀態。

本教學和上一個教學介紹如何將行選取器欄新增至 GridView。 在下一個教程中,我們將探討如何稍作努力,將插入功能新增至 GridView。

快樂的程序設計!

關於作者

斯科特·米切爾,七本 ASP/ASP.NET 書籍和 4GuysFromRolla.com 創始人的作者,自1998年以來一直與Microsoft Web 技術合作。 斯科特擔任獨立顧問、教練和作家。 他的最新書是 Sams Teach Yourself ASP.NET 2.0 in 24 Hours。 可以透過 mitchell@4GuysFromRolla.com 聯絡他。