前端:ScriptManager → UpdatePanel 包裹 Repeater + AspNetPager → 非同步 PostBack 只更新面板內容。
CREATE PROCEDURE P_Pager
@PageNumber INT, @PageSize INT
AS
BEGIN
DECLARE @sql NVARCHAR(4000);
SET @sql = N'SELECT TOP ' + CAST(@PageSize AS VARCHAR) +
N' * FROM T_Test WHERE [type]=1 AND id NOT IN (' +
N'SELECT TOP ' + CAST((@PageNumber-1)*@PageSize AS VARCHAR) +
N' id FROM T_Test ORDER BY id DESC) ORDER BY id DESC';
EXEC sp_executesql @sql;
END
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<ul>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li>
<p><span><%# Eval("username") %>:</span><%# Eval("content") %></p>
<p><em>發表時間:<%# Eval("addtime") %></em></p>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
總記錄:<asp:Literal ID="ltlCount" runat="server" />
<webdiyer:AspNetPager ID="AspNetPager1" runat="server"
AlwaysShow="true" PageIndexBoxType="DropDownList"
OnPageChanged="AspNetPager1_PageChanged" />
</ContentTemplate>
</asp:UpdatePanel>
public partial class AjaxPager : Page
{
int _pageSize = 5;
int CurrentPage
{
get { return (int)(ViewState["cp"] ?? 1); }
set { ViewState["cp"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) { CurrentPage = 1; BindData(); }
AspNetPager1.PageChanged += AspNetPager1_PageChanged;
}
void AspNetPager1_PageChanged(object sender, EventArgs e)
{
CurrentPage = AspNetPager1.CurrentPageIndex;
BindData();
}
int GetCount()
{
using (var conn = GetConn())
using (var cmd = new SqlCommand("SELECT COUNT(*) FROM T_Test WHERE [type]=1", conn))
{
conn.Open();
return (int)cmd.ExecuteScalar();
}
}
void BindData()
{
ltlCount.Text = GetCount().ToString();
var prms = new[] {
new SqlParameter("@PageNumber", CurrentPage),
new SqlParameter("@PageSize", _pageSize)
};
var dt = ExecProc("P_Pager", prms);
AspNetPager1.PageSize = _pageSize;
AspNetPager1.RecordCount = GetCount();
AspNetPager1.CurrentPageIndex = CurrentPage;
Repeater1.DataSource = dt.DefaultView;
Repeater1.DataBind();
}
DataTable ExecProc(string proc, SqlParameter[] prms)
{
using (var conn = GetConn())
using (var cmd = new SqlCommand(proc, conn) { CommandType = CommandType.StoredProcedure })
using (var da = new SqlDataAdapter(cmd))
{
if (prms != null) cmd.Parameters.AddRange(prms);
var ds = new DataSet();
conn.Open(); da.Fill(ds);
return ds.Tables[0];
}
}
SqlConnection GetConn() => new SqlConnection(
"Data Source=127.0.0.1;Initial Catalog=testDB;User ID=sa;Password=123456");
}
ScriptManager 必備,啟用部分渲染UpdatePanel 範圍僅包含需更新區塊,避免整頁重繪AspNetPager 設定 OnPageChanged 事件,內部自動觸發非同步回傳NOT IN (SELECT TOP ...) 邏輯分頁,SQL 2005 相容fetch + Web API / Generic Handler 回傳 JSONDataTables.js、Bootstrap Table 客戶端分頁/排序OFFSET/FETCH (SQL 2012+) 高效分頁此範例展示 WebForms 時代 AJAX 無刷新分頁標準做法,理解生命週期與 ViewState 管理是關鍵。