我有一个网格视图,它链接到数据库表。数据库表中共有 2,050 条记录。我想每页显示 25 条记录。
以下是重要变量的输出:
问题: Gridview
GridView1_PageIndexChanging
仅显示 2 页。根据变量 aboce,这是不正确的 bc,我们知道总共应该是 79 页。
问题原因:
<asp:GridView ... PageSize="25">
gridview 每页显示 25 条记录。比在后端我设置了全局变量 Dim pageSize As Integer = 26
(用于测试 i inc 25 到 26)。
Sql 查询正在从数据库加载 26 条记录并放入 Gridview。第一页有 25 条记录,第二页有 1 条记录。等于 26 条记录
*** note如果我更改为
Dim pageSize As Integer = 25
,则在gridview上分页将为0,因为gridview分页似乎基于sql查询第一个结果而不是表中的总计数。
我想要什么:我想显示全部79页。不只是 2 页。
代码:
前端:我有一个页面大小= 25 的网格视图
<asp:GridView ... PageSize="25" AllowPaging="true" PageSize="25" OnPageIndexChanging="GridView1_PageIndexChanging">
全局变量:
Dim currentPageIndex As Integer = 0 ' Stores the current page index (starts from 0).
Dim pageSize As Integer = 26 ' Defines the number of records per page (set to 26).
Dim sortColumn As String = "" ' Holds the name of the currently sorted column (initially empty).
Dim sortDirection As SortDirection = sortDirection.Ascending ' Tracks the current sorting direction (ascending by default).
主要方法:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
BindGridData()
End If
End Sub
Gridview分页功能:
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
GridView1.PageIndex = e.NewPageIndex
BindGridData(pageIndex:=e.NewPageIndex)
End Sub
从数据库加载数据并将其链接到gridview:
Protected Sub BindGridData(Optional ByVal pageIndex As Integer = 0,
Optional ByVal sortColumn As String = "",
Optional ByVal sortDirection As String = "ASC")
Dim sqlConn1 As New OdbcConnection(myConnectionString1)
Try
sqlConn1.Open()
Dim queryString As String = "SELECT * FROM MyTable "
' Add ORDER BY clause for sorting - Use the correct SortDirection enumeration value for ASC or DESC
If Not String.IsNullOrEmpty(sortColumn) Then
queryString &= " ORDER BY " & sortColumn & " " & sortDirection.ToString()
End If
' Add paging logic using LIMIT and OFFSET clauses
queryString &= " OFFSET " & (pageIndex * pageSize) & " ROWS FETCH NEXT " & pageSize & " ROWS ONLY "
Dim adapter As OdbcDataAdapter = New OdbcDataAdapter(queryString, sqlConn1)
Dim dt As DataTable = New DataTable()
adapter.Fill(dt)
Dim totalRecords As Integer = GetTotalRecordCount() ' total records count from database
' Bind data to GridView
If totalRecords > 0 Then
GridView1.DataSource = dt
GridView1.DataBind()
CountL.Text = dt.Rows.Count & " Records " & totalRecords & " =GetTotalRecordCount() " & (pageIndex + 1) & " of " & (Math.Ceiling(totalRecords / pageSize)) & " Pages"
Else
CountL.Text = "No records found."
End If
sqlConn1.Close()
Catch ex As Exception
' Handle exception
End Try
End Sub
获取TotalRecordCount方法:
Private Function GetTotalRecordCount() As Integer
Dim sqlConn2 As New OdbcConnection(myConnectionString1)
Try
sqlConn2.Open()
Dim countQuery As String = "SELECT COUNT(*) FROM MyTable "
Dim cmd As OdbcCommand = New OdbcCommand(countQuery, sqlConn2)
Dim totalRecords As Integer = CInt(cmd.ExecuteScalar())
Return totalRecords
Finally
sqlConn2.Close()
End Try
End Function
好吧,如果您真的想要一个有 78 个值的寻呼机,我们还没有解决?
我想这是可能的,但我从来没有见过这样一个有这么多选择的寻呼机。
如前所述,在您发布的代码中,您会得到一个 RowCount,但永远不要将该 RowCount 提供给寻呼机。并且内置的数据分页器没有该选项。如前所述,内置数据分页器适用于完整数据集。
如前所述,我使用计算机已有 30 年,从未见过具有 78 个选项的数据寻呼机!
但是,这肯定是可能的,这意味着我们必须推出自己的寻呼机。
因此,我们需要一个可以有 1 到“N”种选择的控件。最好的选择是 RadioButton 列表。
所以,我的网格行非常大,所以我每页 12 行。
每行 12 个按钮,对于 2000 行的数据库,大约有 2000/12 = 166 个按钮。然而,79还是160?太多了!!!
所以,说出这个标记:
<div style="width: 50%">
<asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Edit"
ItemStyle-HorizontalAlign="Center" ItemStyle-Width="130px">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Select"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<br />
<div style="width: 100%">
<asp:RadioButtonList ID="RadioPager" runat="server"
AppendDataBoundItems="True"
RepeatDirection="Horizontal"
DataTextField="Value"
DataValueField="Key" CssClass="rMyChoice"
AutoPostBack="true"
OnSelectedIndexChanged="RadioPager_SelectedIndexChanged"
RepeatColumns="30">
</asp:RadioButtonList>
</div>
</div>
我们的代码来加载和管理分页?
嗯,使用 RadioButton 列表的一个很好的功能是它会“记住”当前按钮,这将成为我们当前的页面设置。
因此这段代码:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
FirstDataLoad()
ViewState("NumPages") = NumPages
Else
NumPages = ViewState("NumPages")
End If
End Sub
Sub FirstDataLoad()
Dim NumPages As Integer = 0
Dim NumPagesD As Decimal = GetRowCount() / PageSize
NumPages = Int(NumPagesD) ' decimal to integer
If NumPagesD > NumPages Then
NumPages += 1 ' add 1 if some rows on last page
End If
Dim butListSource As New Dictionary(Of Integer, Integer)
For i = 1 To NumPages
butListSource.Add(i, i) 'value and display are same (but do NOT have to be!)
Next
RadioPager.DataSource = butListSource
RadioPager.DataBind()
RadioPager.SelectedIndex = 0 ' list is zero based, but we use PageIndex starting at 1
Dim strSQL As String =
"SELECT * FROM tblHotels2 ORDER BY ID"
GVHotels.DataSource = GetData(strSQL)
GVHotels.DataBind()
End Sub
Public Function GetRowCount() As Integer
Dim strSQL = "SELECT COUNT(*) FROM tblHotels2"
GetRowCount = MyRst(strSQL).Rows(0)(0)
End Function
Public Function GetData(strSQL As String) As DataTable
' assume that RadioButon index (zero based page number
' is ALWAYS set BEFORE calling this routine
Dim PageNumber = RadioPager.SelectedIndex + 1
Dim strSQL2 As String = strSQL &
" OFFSET ((@PageNumber - 1) * @RowsPerPage) ROWS
FETCH NEXT @RowsPerPage ROWS ONLY;"
Dim cmdSQL As New SqlCommand(strSQL2)
cmdSQL.Parameters.Add("@PageNumber", SqlDbType.Int).Value = PageNumber
cmdSQL.Parameters.Add("@RowsPerPage", SqlDbType.Int).Value = PageSize
Return MyRstP(cmdSQL)
End Function
所以,代码不是很多,但更重要的是代码是否可读。
单选按钮“索引已更改”的工作方式非常类似于组合框,代码是这样的:
Protected Sub RadioPager_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim strSQL As String =
"SELECT * FROM tblHotels2 ORDER BY ID"
GVHotels.DataSource = GetData(strSQL)
GVHotels.DataBind()
End Sub
请非常仔细地注意我们如何保留页数。请记住,全局表单值在回发之间不会持续存在(它们超出范围)。回发后,服务器不会在内存中保留代码的副本。毕竟,用户可能会合上笔记本电脑的盖子,或者现在可能正在亚马逊上购物。
因此,基于网络的软件就是我们所说的“无状态”。页面、代码变量在每次新回发时都从头开始。这就是网站的工作原理。
我运行上面页面的结果是这样的: