ASP:带有分页的 Gridview 复选框列未显示选中了哪个复选框

Posted

技术标签:

【中文标题】ASP:带有分页的 Gridview 复选框列未显示选中了哪个复选框【英文标题】:ASP:Gridview checkbox column with paging is not showing which checkbox is checked 【发布时间】:2022-01-03 13:40:53 【问题描述】:

在 Asp:GridView (ASP.NET/VB) 中,我有一列复选框:

<asp:TemplateField HeaderText=" " ItemStyle-BorderWidth="1" HeaderStyle-Width="3%" ItemStyle-Width="3%" HeaderStyle-CssClass="box_border table_title" ItemStyle-CssClass="box_border ">
    <ItemTemplate>               
    <asp:CheckBox ID="chkHaktzaa"  runat="server"/>
    </ItemTemplate>
</asp:TemplateField>

而且我在网格中也有分页:

<table id="pager" align="center" dir="ltr" clientidmode="Static" runat="server" cellspacing="0" cellpadding="0">
<tr>
<td id="last" class="last" runat="server" clientidmode="Static"></td>
<td id="next" runat="server" tooltip="הבא" class="next" clientidmode="Static"></td>
<td>
<input id="pageNum" runat="server" class="pagedisplay" clientidmode="Static" />
</td>
<td class="prev" clientidmode="Static"></td>
<td class="first" clientidmode="Static"></td>
<td>
<select id="numOfRec" runat="server" class="pagesize" clientidmode="Static">
<option selected="selected" value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</select>
</td>
</tr>
</table>

在代码隐藏中,当我遍历这些网格行并以编程方式访问 CheckBox 控件,然后查阅其Checked 属性以确定它是否已被选中时,它仅适用于网格的当前页面。它不考虑其他页面。

其他页面上的行总是为选中返回 false。

这是迭代循环:

For Each row As GridViewRow In gvBakashot.Rows
   Dim cb As CheckBox = row.FindControl("chkHaktzaa")
   If cb IsNot Nothing And cb.Checked Then
      lst.Add(count)
   End If
   count = count + 1
Next

感谢您的帮助。

【问题讨论】:

【参考方案1】:

当然,当您重新加载页面并将整个网格重新加载到新的数据页面时,未绑定的复选框将不会保留或记住它的值。

这意味着您需要将复选框获取/抓取/保存到一些持续存在的集合中,然后在网格显示/重新加载时,您必须重新设置复选框。

换句话说,如果你跳转到一个新页面,那么你正在对页面和网格进行 100% 全新的重新加载 - 当然,一些旧的先前加载的网格将不记得选中了哪些复选框.

因此,您需要管理(保存)复选框。因此,唯一的问题就变成了我们是否在选中每个复选框或页面时执行此操作 - 实际上是我们需要在这里回答的唯一问题。

您没有提及您显示的行数 - 但给定页面的网格将持续存在(假设您正确编写了此内容并且在页面回发时不要重新加载网格。换句话说,您的页面加载事件仅在第一页加载时加载网格(PostBack = false)。假设这个关键的设计问题?(您编写的所有页面和每个页面都更好地遵循此规则!!!)。

好的,那么,我建议这样做:

这是标记:

        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
            DataKeyNames="ID" CssClass="table" Width="50%" AllowPaging="True">
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="FirstName"     />
                <asp:BoundField DataField="LastName" HeaderText="LastName"       />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName"     />
                <asp:BoundField DataField="City" HeaderText="City"               />
                <asp:BoundField DataField="Description" HeaderText="Description" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox ID="ckSel" runat="server" 
                            Checked='<%# MyChecked(Eval("ID")) %>'
                            AutoPostBack="true"
                            OnCheckedChanged="ckSel_CheckedChanged"
                            />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <PagerStyle CssClass="GridPager" />
        </asp:GridView>

我们填充网格的代码是这样的:

Dim MyCheckList As New List(Of Integer)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadGrid()
        ViewState("CheckList") = MyCheckList
    Else
        MyCheckList = ViewState("CheckList")
    End If

End Sub

Sub LoadGrid()
    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand("SELECT * from tblHotels ORDER BY HotelName", conn)

            Dim rstData As New DataTable
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
            GridView1.DataSource = rstData
            GridView1.DataBind()

        End Using
    End Using
End Sub

Public Function MyChecked(ID As Integer) As Boolean

    Return MyCheckList.Contains(ID)

End Function

现在我们如何将该“列表”保存到页面。

现在,为上面的复选框编写代码是一件简单的事情。

那个代码很简单,而且这个:

Protected Sub ckSel_CheckedChanged(sender As Object, e As EventArgs)

    ' user click on check box
    Dim ckSel As CheckBox = sender
    Dim gRow As GridViewRow = ckSel.Parent.Parent
    Dim PKID As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")

    If ckSel.Checked Then
        ' add to our collection
        MyCheckList.Add(PKID)
    Else
        ' remove from check list
        MyCheckList.Remove(PKID)
    End If

End Sub

结果现在是这样的:

因此,现在 mylist 将维护并保留您所做选择的列表。

然后你可以说这样做:

    ' get selected data
    Dim rstData As New DataTable

    Dim strWhere As String = String.Join(",", MyCheckList.ToArray())
    Dim strSQL As String
    strSQL = "SELECT * from tblHotels WHERE ID IN(" & strWhere & ") ORDER BY HotelName"

    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using

    ' now do whatever, 

    For Each OneRow As DataRow In rstData.Rows
        ' do whatever
    Next

这样你就可以传递 PK id 列表了。

注意在上面也要非常小心,我们没有显示,甚至必须显示每一行的 PK 值——我们为此使用了 DataKeys。这有很多原因,但重要的是我们不会在网格或标记中公开 PK 数据库 ID。出于安全原因,这非常好,这也意味着我们也没有在网格标记中包含 PK ID,我们甚至不必隐藏 pk 列 - 这就是 DataKeys 功能的用途。

编辑:公平地说?我确实使用了 Eval("ID") - 并且确实在 GV 中公开了 ID - 但实际上我不必这样做(代码更短)。

【讨论】:

以上是关于ASP:带有分页的 Gridview 复选框列未显示选中了哪个复选框的主要内容,如果未能解决你的问题,请参考以下文章

asp.net中GridView怎样进行分页,编辑,删除操作

带有复选框控件的 ASP.Net GridView 和 Jquery dataTable

asp.net 带有gridview的分页无刷新,急求,使用ajax

gridview 分页问题,成功分页了,为啥点击第x页时显示空白?

DataTables 1.10 全选复选框以选择所有行,甚至是带有分页的隐藏行

使用 ajax 和分页的带有 ASP 下拉列表控件的 Select2