共用方式為


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

作者:Scott Mitchell

下載 PDF

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

簡介

在上一個教學課程中,我們已檢查如何將單選按鈕的數據行新增至 GridView,以便選取特定記錄。 單選按鈕的數據行是適當的使用者介面,當使用者只能從方格中選擇最多一個專案時。 不過,我們有時可能會想要允許使用者從方格挑選任意數目的專案。 例如,網頁式電子郵件用戶端通常會顯示含有複選框列的郵件清單。 用戶可以選取任意數目的郵件,然後執行一些動作,例如將電子郵件移至另一個資料夾或刪除它們。

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

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

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

步驟 1:新增 清單 產品資訊的 Paged GridView

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

建立名為 ProductsDataSource 的新 ObjectDataSource

圖 2:建立名為 ProductsDataSource 的新 ObjectDataSource (按兩下即可檢視大小完整的映射)

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

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

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

圖 4:將 UPDATE、INSERT 和 DELETE 索引標籤中的 Drop-Down 清單 設定為 ([無]) (按兩下即可檢視完整大小的映像)

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

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

進行這些變更之後,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 s 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。 如果核取 CheckBox,則會從集合擷取數據列的DataKeys對應ProductID值。 在此練習中 DeleteResults ,我們只會在標籤中顯示資訊訊息,但在工作應用程式中,我們會改為呼叫 ProductsBLL 類別 s DeleteProduct(productID) 方法。

新增此事件處理程式后,按兩下 [刪除選取的產品] 按鈕現在會顯示 ProductID 所選產品的 s。

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

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

步驟 4:新增 [全部檢查] 和 [取消核取所有按鈕]

如果使用者想要刪除目前頁面上的所有產品,他們必須勾選十個複選框的每一個。 我們可以藉由新增 [全部核取] 按鈕來協助加速此程式,按兩下時,會選取方格中的所有複選框。 取消核取 [全部] 按鈕會同樣有説明。

將兩個按鈕 Web 控件新增至頁面,並將其放在 GridView 上方。 將第一個 設定 IDCheckAll ,並將其 Text 屬性設定為 [全部檢查];將第二個 設定 IDUncheckAll ,並將其 Text 屬性設定為 [全部取消核取]。

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

接下來,在名為 ToggleCheckState(checkState) 的程式代碼後置類別中建立方法,並在叫用時列舉 Products GridView s 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:按兩下 [核取所有按鈕] 選取 [所有複選框] (按鍵即可檢視大小完整的影像)

注意

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

摘要

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

本教學課程和最後一個查看將數據列選取器數據行新增至 GridView。 在下一個教學課程中,我們將探討如何使用一些工作,將插入功能新增至 GridView。

快樂的程序設計!

關於作者

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