使用自定义分页在 ASP.NET GridView 控件中显示新闻文章列表
在具有自定义分页的 ASP.NET GridView 控件中显示新闻文章列表。
引言
我正在开发一个网站,需要一种在 GridView
控件中显示新闻文章的方法,但允许一次分页浏览一定数量的文章,这样如果用户查看完整的存档,页面就不会太长。
GridView
控件中的默认分页效果不佳,因为它总是从数据库中检索所有记录,然后只显示您想要的记录。 我更希望只获取当前页面所需的记录,并让 SQL Server 完成所有工作,从而减少对 Web 应用程序的影响。
在网上搜索后,我找到了一些文章,但没有一个真正适合我,所以我决定自己编写一个。 顺便说一句,我首先在一张纸上画出逻辑,然后再深入研究代码,这确实有助于我集中注意力,并确保我没有浪费时间走错误的方向。 让我们开始编写代码...
使用代码
首先,我的 SQL 新闻文章表的结构如下
UniqueID
NewsCategory
DatePosted
标题
正文
显示
UniqueID
是一个自动递增的标识列,Display
列是一个位(True/False)。
因此,除了分页之外,我还需要能够按 NewsCategory
过滤我的记录,以及搜索在 Title
或 Body
字段中找到的单词。 为此,我创建了一个存储过程,如下所示
CREATE PROCEDURE spGetNews
@iPageIndex INT,
@iMaxRows INT,
@iCategory INT,
@strSearch VARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @iStart INT
SELECT @iStart = (@iPageIndex - 1) * @iMaxRows
DECLARE @iEnd INT
SELECT @iEnd = @iStart + @iMaxRows
IF OBJECT_ID (N'#TempNews',N'U') IS NOT NULL
DROP TABLE #TempNews
CREATE TABLE #TempNews(
intUniqueID INT PRIMARY KEY IDENTITY(1, 1),
dtPosted DATETIME,
strTitle VARCHAR(100),
strBody VARCHAR (5000),
strNewsCategory VARCHAR(50)
)
INSERT #TempNews
SELECT N.dtPosted,
N.strTitle,
N.strBody,
C.strNewsCategory
FROM tblNews N
INNER JOIN tblNewsCategory C ON
C.intUniqueID = N.intNewsCategory
WHERE
((@iCategory = 0) OR (intNewsCategory = @iCategory)) AND
((@strSearch = '') OR (strTitle LIKE '%' + @strSearch + '%')) OR
((@strSearch = '') OR (strBody LIKE '%' + @strSearch + '%')) AND
bitActive = 1
ORDER BY dtPosted DESC
SELECT * FROM #TempNews
WHERE intUniqueID > @iStart
AND intUniqueID <= @iEnd
DROP TABLE #TempNews
END
我传递给过程的参数是
@iPageIndex
@iMaxRows
@iCategory
@strSearch
@PageIndex
指的是我们正在查看的当前结果页面。 @iMaxRows
指的是每页显示的记录数 - 请注意,它被称为最大行数,因为最后一页可能包含比其他页面少的记录,具体取决于记录总数。 @iCategory
指的是用于过滤结果的类别,并且是可选的。 @strSearch
指的是用于过滤结果的任何搜索词,也是可选的。
我们首先要做的是根据当前页面和要获取的记录数设置记录集的开始值和结束值。 我们稍后将使用这些值来仅选择相关的记录以传递回我们的 Web 应用程序。
接下来,我们创建一个带有自动递增标识列的临时表 - 这很重要,因为如果从我们的原始新闻文章表中删除记录,ID 将不再是连续的 - 但是,如果我们将记录插入到我们的临时表中,ID 将是连续的,我们可以在开始值和结束值之间进行选择。
然后,我们从新闻文章表中选择适当的记录,并将这些记录插入到我们的临时表中,最后,我们从临时表中选择 ID 介于开始值和结束值之间的结果。 选择它们后,我们从内存中删除我们的临时表。
所以现在,我们有了一个 SQL 存储过程,它将根据一些过滤和分页参数返回一组结果。 我们如何在 Web 应用程序中使用它?
这是我的 *News.aspx* 页面的源代码
<h3>Latest News</h3><br />
<div id="SiteNews" runat="server">
<asp:GridView ID="gvNews" runat="server" AutoGenerateColumns="False"
BorderColor="Black" BorderStyle="Solid" BorderWidth="1px"
GridLines="None" DataKeyNames="intUniqueID" Width="100%">
<Columns>
<asp:BoundField DataField="intUniqueID" Visible="False" />
<asp:BoundField DataField="dtPosted"
DataFormatString="{0:dd/MM/yyyy}" HtmlEncode="False" HeaderText="Posted">
<HeaderStyle HorizontalAlign="Center" Width="70px" />
<ItemStyle HorizontalAlign="Center" Width="70px" />
</asp:BoundField>
<asp:BoundField DataField="strNewsCategory" HeaderText="Category">
<HeaderStyle HorizontalAlign="Center" Width="80px" />
<ItemStyle HorizontalAlign="Center" Width="80px" />
</asp:BoundField>
<asp:BoundField DataField="strTitle" HeaderText="Article Title">
</asp:BoundField>
<asp:HyperLinkField Text="View Complete Atricle">
<HeaderStyle Width="100px" />
<ItemStyle HorizontalAlign="Right" Width="100px" />
</asp:HyperLinkField>
</Columns>
<HeaderStyle BackColor="#CCCCCC" />
<AlternatingRowStyle BackColor="#dbdbfe" />
</asp:GridView>
<div id="Pager" runat="server"> </div>
</div>
请注意,我有两个 div
,一个用于 GridView
控件,另一个名为 Pager
,用于显示分页的页码。 (顺便说一句 - 检查 dtPosted
列,您会看到我指定了日期格式和 HtmlEncode
- 如果 HtmlEncode
未设置为 false
,则不会应用您的格式。)
现在我们有了网格,让我们在代码隐藏页中将数据绑定到它。
在 Page_Load
事件中,我调用以下例程
FillNewsGrid("News.aspx", gvNews, Pager, iMaxRows,
iCurrentPage, iCategory, txtSearchText.Value)
该例程如下所示
Private Sub FillNewsGrid(ByVal strPage As String, ByRef gvGrid As GridView, _
ByRef divPager As HtmlGenericControl, ByVal iMaxRows As Integer, _
Optional ByVal iCurrentPage As Integer = 1, _
Optional ByVal iCategory As Integer = 0, _
Optional ByVal strSearchText As String = "")
If iCurrentPage = 0 Then iCurrentPage = 1
Dim connSql As SqlConnection = New SqlConnection(strConnection)
Dim cmdSql As SqlCommand = New SqlCommand
cmdSql.Connection = connSql
Dim iTotal As Integer = 0
cmdSql.CommandText = "SELECT COUNT (*) FROM tblNews"
connSql.Open()
iTotal = cmdSql.ExecuteScalar
connSql.Close()
cmdSql = New SqlCommand
cmdSql.CommandType = Data.CommandType.StoredProcedure
cmdSql.CommandText = "spGetNews"
cmdSql.Connection = connSql
Dim prmParameter As SqlParameter
prmParameter = New SqlParameter("@iPageIndex", Data.SqlDbType.Int)
prmParameter.Direction = Data.ParameterDirection.Input
prmParameter.Value = iCurrentPage
cmdSql.Parameters.Add(prmParameter)
prmParameter = New SqlParameter("@iMaxRows", Data.SqlDbType.Int)
prmParameter.Direction = Data.ParameterDirection.Input
prmParameter.Value = iMaxRows
cmdSql.Parameters.Add(prmParameter)
prmParameter = New SqlParameter("@iCategory", Data.SqlDbType.Int)
prmParameter.Direction = Data.ParameterDirection.Input
prmParameter.Value = iCategory
cmdSql.Parameters.Add(prmParameter)
prmParameter = New SqlParameter("@strSearch", Data.SqlDbType.VarChar, 100)
prmParameter.Direction = Data.ParameterDirection.Input
prmParameter.Value = strSearchText
cmdSql.Parameters.Add(prmParameter)
connSql.Open()
gvGrid.DataSource = cmdSql.ExecuteReader
gvGrid.DataBind()
connSql.Close()
' Paging
If gvGrid.Rows.Count < 1 Then
divPager.InnerHtml = ""
Else
Dim iPages As Integer = 0
Dim iRemainder As Integer = 0
iPages = iTotal / iMaxRows
iRemainder = iTotal Mod iMaxRows
If iRemainder > iMaxRows Then iPages += 1
If iPages > 1 Then
divPager.InnerHtml = "Page: "
Dim i As Integer = 0
For i = 1 To iPages
If i <> iCurrentPage Then
divPager.InnerHtml += "<a href=""" & strPage & _
"?pg=" & i & """>" & i & "</a>"
Else
divPager.InnerHtml += i.ToString
End If
If i < iPages Then divPager.InnerHtml += " | "
Next
End If
End If
End Sub
最后,我编译链接以在 RowDataBound
事件中查看完整的文章
Protected Sub gvNews_RowDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
Handles gvNews.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
' Build link to full article
e.Row.Cells(4).Text = "<a href=""NewsArticle.aspx?id=" & _
gvNews.DataKeys(e.Row.RowIndex)("intUniqueID") & _
"&pg=" & iCurrentPage & "&cID=" & _
iCategory & """>View complete article</a>"
End If
End Sub
就这样,这应该可以帮助您入门。 如果您在站点上启动并运行此程序需要任何帮助,请随时与我联系。