添加 GridView 复选框列 (VB)

作者 :Scott Mitchell

下载 PDF

本教程介绍如何将包含检查框的列添加到 GridView 控件,以便为用户提供一种直观的方式来选择 GridView 的多行。

简介

在前面的教程中,我们介绍了如何向 GridView 添加一列单选按钮,以便选择特定记录。 当用户最多只能从网格中选择一项时,单选按钮列是合适的用户界面。 但是,有时,我们可能希望允许用户从网格中选择任意数量的项。 例如,基于 Web 的电子邮件客户端通常显示包含一列复选框的邮件列表。 用户可以选择任意数量的邮件,然后执行某些操作,例如将电子邮件移动到另一个文件夹或删除它们。

在本教程中,我们将了解如何添加复选框列,以及如何确定在回发时选中的复选框。 具体而言,我们将生成一个示例,该示例密切模拟基于 Web 的电子邮件客户端用户界面。 我们的示例将包含一个分页的 GridView,其中列出了数据库表中的产品 Products ,每一行都有一个复选框, (请参阅图 1) 。 单击“删除所选产品”按钮将删除所选产品。

每个产品行都包含一个复选框

图 1:每个产品行包含一个复选框 (单击以查看全尺寸图像)

步骤 1:添加Lists产品信息的分页 GridView

在担心添加一列复选框之前,首先让我们重点介绍在支持分页的 GridView 中列出产品。 首先打开 文件夹中的页面CheckBoxField.aspxEnhancedGridView,将“工具箱”中的 GridView 拖到Designer,并将其ID设置为 Products。 接下来,选择将 GridView 绑定到名为 ProductsDataSource的新 ObjectDataSource。 将 ObjectDataSource 配置为使用 ProductsBLL 类,并调用 GetProducts() 方法来返回数据。 由于此 GridView 是只读的,因此请将“更新”、“插入”和“删除”选项卡中的下拉列表设置为 (“无”) 。

创建新的对象DataSource 名为 ProductsDataSource

图 2:新建名为 ProductsDataSource 的对象数据源 (单击以查看全尺寸图像)

配置 ObjectDataSource 以使用 GetProducts () 方法检索数据

图 3:使用 方法配置 ObjectDataSource 以检索数据 GetProducts() (单击以查看全尺寸图像)

将“更新”、“插入”和“删除”选项卡中的 Drop-Down Lists 设置为“无 (”)

图 4:将“更新”、“插入”和“删除”选项卡中的 Drop-Down Lists 设置为“无 (”) (单击以查看全尺寸图像)

完成“配置数据源”向导后,Visual Studio 将自动为与产品相关的数据字段创建 BoundColumns 和 CheckBoxColumn。 与在上一教程中一样,删除除 、 CategoryNameUnitPrice BoundFields 外ProductName的所有字段,并将HeaderText属性更改为“产品”、“类别”和“价格”。 配置 UnitPrice BoundField,使其值的格式设置为货币。 此外,通过选中智能标记中的“启用分页”复选框,将 GridView 配置为支持分页。

我们还添加用于删除所选产品的用户界面。 在 GridView 下添加一个按钮 Web 控件,将其IDDeleteSelectedProducts设置为 ,将其Text属性设置为“删除所选产品”。 对于本示例,我们只会显示一条消息,说明要删除的产品,而不是实际从数据库中删除产品。 若要适应这种情况,请在“按钮”下面添加标签 Web 控件。 将其 ID 设置为 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) 。 此时,应会看到前 10 个产品的名称、类别和价格。

列出前十种产品的名称、类别和价格

图 5:列出前十种产品的名称、类别和价格 (单击以查看全尺寸图像)

步骤 2:添加复选框列

由于 ASP.NET 2.0 包含 CheckBoxField,因此人们可能认为它可用于向 GridView 添加复选框列。 遗憾的是,情况并非如此,因为 CheckBoxField 旨在用于布尔数据字段。 也就是说,若要使用 CheckBoxField,必须指定其值的基础数据字段,以确定是否选中呈现的复选框。 我们不能使用 CheckBoxField 仅包含未选中复选框的列。

相反,我们必须添加 TemplateField 并将 CheckBox Web 控件添加到其 ItemTemplate。 继续将 TemplateField 添加到 GridView, Products 使其成为最左侧的第一个 () 字段。 在 GridView 智能标记中,单击“编辑模板”链接,然后将 CheckBox Web 控件从工具箱拖到 中 ItemTemplate。 将此 CheckBox 属性 ID 设置为 ProductSelector

将 CheckBox Web 控件 Named ProductSelector 添加到 TemplateField s ItemTemplate

图 6:将名为 ProductSelector 的 CheckBox Web 控件添加到 TemplateField (ItemTemplate单击以查看全尺寸图像)

添加 TemplateField 和 CheckBox Web 控件后,每一行现在都包含一个复选框。 图 7 显示了在添加 TemplateField 和 CheckBox 后通过浏览器查看的此页面。

每个产品行现在包含一个复选框

图 7:每个产品行现在包含一个复选框 (单击以查看全尺寸图像)

步骤 3:确定在回发时选中了哪些复选框

此时,我们有一列复选框,但无法确定在回发时选中了哪些复选框。 但是,单击“删除所选产品”按钮时,我们需要知道选中了哪些复选框才能删除这些产品。

GridView 属性Rows提供对 GridView 中的数据行的访问。 我们可以循环访问这些行,以编程方式访问 CheckBox 控件,然后查阅其 Checked 属性以确定是否已选择 CheckBox。

DeleteSelectedProducts Button Web 控件 事件 Click 创建事件处理程序,并添加以下代码:

Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
    Handles DeleteSelectedProducts.Click
    
    Dim atLeastOneRowDeleted As Boolean = False
    ' Iterate through the Products.Rows property
    For Each row As GridViewRow In Products.Rows
        ' Access the CheckBox
        Dim cb As CheckBox = row.FindControl("ProductSelector")
        If cb IsNot Nothing AndAlso cb.Checked Then
            ' Delete row! (Well, not really...)
            atLeastOneRowDeleted = True
            ' First, get the ProductID for the selected row
            Dim productID As Integer = _
                Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
            ' "Delete" the row
            DeleteResults.Text &= String.Format( _
                "This would have deleted ProductID {0}<br />", productID)
            '... To actually delete the product, use ...
            ' Dim productAPI As New ProductsBLL
            ' productAPI.DeleteProduct(productID)
            '............................................
        End If
    Next
    ' Show the Label if at least one row was deleted...
    DeleteResults.Visible = atLeastOneRowDeleted
End Sub

属性 Rows 返回构成 GridView 数据行的实例集合 GridViewRow 。 此处的 For Each 循环枚举此集合。 对于每个 GridViewRow 对象,使用 以编程方式访问 row.FindControl("controlID")行 CheckBox。 如果选中 CheckBox,则会从DataKeys集合中检索行对应的ProductID值。 在本练习中,我们只是在 Label 中 DeleteResults 显示一条信息性消息,但在工作应用程序中,我们将改为调用 ProductsBLL 类 s DeleteProduct(productID) 方法。

添加此事件处理程序后,单击“删除所选产品”按钮现在会显示 ProductID 所选产品的 。

单击“删除所选产品”按钮时,将列出所选产品的产品ID

图 8:单击“删除所选产品”按钮时,“所选产品 ProductID ”将列出 (单击以查看全尺寸图像)

步骤 4:添加“全部选中”和“取消选中所有”按钮

如果用户想要删除当前页上的所有产品,则必须检查十个复选框中的每一个。 我们可以通过添加“全部选中”按钮来帮助加快此过程,单击该按钮时会选中网格中的所有复选框。 取消选中“全部”按钮同样有用。

将两个按钮 Web 控件添加到页面,将它们放置在 GridView 上方。 将第一个 设置为 ,CheckAll将其属性设置为 Check All;将第二个 IDUncheckAll 设置为 ,将其Text属性设置为 Uncheck All 。TextID

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

接下来,在名为 ToggleCheckState(checkState) 的代码隐藏类中创建一个方法,该方法在调用时枚举 Products GridView 的 Rows 集合,并将每个 CheckBox 属性 Checked 设置为传入的 checkState 参数的值。

Private Sub ToggleCheckState(ByVal checkState As Boolean)
    ' Iterate through the Products.Rows property
    For Each row As GridViewRow In Products.Rows
        ' Access the CheckBox
        Dim cb As CheckBox = row.FindControl("ProductSelector")
        If cb IsNot Nothing Then
            cb.Checked = checkState
        End If
    Next
End Sub

接下来,为 CheckAllUncheckAll 按钮创建Click事件处理程序。 在 CheckAll 事件处理程序中,只需调用 ToggleCheckState(True);在 中 UncheckAll,调用 ToggleCheckState(False)

Protected Sub CheckAll_Click(sender As Object, e As EventArgs) _
    Handles CheckAll.Click
    
    ToggleCheckState(True)
End Sub
Protected Sub UncheckAll_Click(sender As Object, e As EventArgs) _
    Handles UncheckAll.Click
    
    ToggleCheckState(False)
End Sub

使用此代码,单击“全部检查”按钮会导致回发并检查 GridView 中的所有复选框。 同样,单击“全部取消选中”将取消选中所有复选框。 图 9 显示了选中“全部检查”按钮后的屏幕。

单击“全部选中”按钮选择所有复选框

图 9:单击“全部选中”按钮选择所有复选框 (单击以查看全尺寸图像)

注意

显示复选框列时,选择或取消选择所有复选框的一种方法是通过标题行中的复选框。 此外,当前的 Check All/Uncheck All 实现需要回发。 但是,可以完全通过客户端脚本选中或取消选中复选框,从而提供快速的用户体验。 若要详细了解如何使用“全部选中”和“全部取消选中”的标题行复选框,以及有关使用客户端技术的讨论,检查使用 Client-Side 脚本签出 GridView 中的所有 CheckBox 和 Check All CheckBox

总结

如果需要让用户在继续操作之前从 GridView 中选择任意数量的行,添加复选框列是一个选项。 正如我们在本教程中看到的,在 GridView 中包含一列复选框需要添加具有 CheckBox Web 控件的 TemplateField。 使用 Web 控件 (而不是直接将标记注入模板,如上一教程中所做的那样,) ASP.NET 自动记住什么是 CheckBox,并且未在回发中检查。 我们还可以以编程方式在代码中访问 CheckBox,以确定是否选中给定的 CheckBox 或更改选中状态。

本教程和最后一个教程介绍了如何向 GridView 添加行选择器列。 在下一教程中,我们将探讨如何通过一些工作向 GridView 添加插入功能。

编程愉快!

关于作者

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