Access 資料庫在中小型專案中仍常見,但無內建分頁功能。ASP.NET PagedDataSource 類別可在記憶體中對 DataTable/DataView 進行分頁。本文提供完整實作:自訂分頁 UI(首頁/上頁/下頁/末頁、頁碼下拉、每頁筆數輸入)、PagedDataSource 綁定 Repeater、狀態同步邏輯。
<div class="page" id="ctrlRecordPage">
總<asp:Label ID="Zpage" runat="server" Text="1"></asp:Label>頁 /
<asp:Label ID="Zcount" runat="server" Text="0"></asp:Label>筆
<asp:LinkButton ID="start_button" runat="server" OnClick="start_button_Click">首頁</asp:LinkButton>
<asp:LinkButton ID="up_button" runat="server" OnClick="up_button_Click">上一頁</asp:LinkButton>
<asp:LinkButton ID="down_button" runat="server" OnClick="down_button_Click">下一頁</asp:LinkButton>
<asp:LinkButton ID="end_button" runat="server" OnClick="end_button_Click">末頁</asp:LinkButton>
每頁<asp:TextBox ID="Pagesize" runat="server" Text="10" Width="30px"></asp:TextBox>筆
當前<asp:DropDownList ID="Pageing" runat="server" AutoPostBack="True" OnSelectedIndexChanged="Pageing_SelectedIndexChanged"></asp:DropDownList>頁
</div>
<asp:Repeater ID="listshow_Repeater" runat="server">
<ItemTemplate>
<div><%# Eval("Title") %></div>
</ItemTemplate>
</asp:Repeater>
private void Pageing_databind(int currentPage)
{
Pageing.Items.Clear();
int totalPages = Convert.ToInt32(Zpage.Text);
if (totalPages > 0)
{
for (int i = 1; i <= totalPages; i++)
Pageing.Items.Add(i.ToString());
}
else
{
Pageing.Items.Add("1");
}
if (Pageing.Items.FindByValue(currentPage.ToString()) != null)
Pageing.SelectedValue = currentPage.ToString();
// 控制按鈕啟用狀態
if (totalPages > 1)
{
Pageing.Enabled = true;
int selPage = Convert.ToInt32(Pageing.SelectedValue);
start_button.Enabled = up_button.Enabled = (selPage > 1);
down_button.Enabled = end_button.Enabled = (selPage < totalPages);
}
else
{
start_button.Enabled = up_button.Enabled = down_button.Enabled = end_button.Enabled = false;
Pageing.Enabled = false;
}
}
protected void start_button_Click(object sender, EventArgs e) { NavigateToPage(1); }
protected void up_button_Click(object sender, EventArgs e)
{
int p = Convert.ToInt32(Pageing.SelectedValue);
if (p > 1) NavigateToPage(p - 1);
}
protected void down_button_Click(object sender, EventArgs e)
{
int p = Convert.ToInt32(Pageing.SelectedValue);
int total = Convert.ToInt32(Zpage.Text);
if (p < total) NavigateToPage(p + 1);
}
protected void end_button_Click(object sender, EventArgs e) { NavigateToPage(Convert.ToInt32(Zpage.Text)); }
protected void Pageing_SelectedIndexChanged(object sender, EventArgs e) { DataBindGrid(); }
private void NavigateToPage(int page)
{
if (Pageing.Items.FindByValue(page.ToString()) != null)
Pageing.SelectedValue = page.ToString();
DataBindGrid();
}
protected void DataBindGrid()
{
// 1. 取得資料 (此處示範直接查詢,實務建議加快取/分頁存儲程序)
DataTable dt = GetDataTable("SELECT * FROM AdList ORDER BY CreateTime DESC");
// 2. PagedDataSource 分頁
PagedDataSource pds = new PagedDataSource();
pds.DataSource = dt.DefaultView;
pds.AllowPaging = true;
int pageSize = 10;
if (int.TryParse(Pagesize.Text, out int sz) && sz > 0) pageSize = sz;
pds.PageSize = pageSize;
Zcount.Text = pds.DataSourceCount.ToString();
Zpage.Text = pds.PageCount.ToString();
int currentPage = 1;
if (Pageing.SelectedIndex > -1) currentPage = Convert.ToInt32(Pageing.SelectedValue);
Pageing_databind(currentPage);
pds.CurrentPageIndex = currentPage - 1; // 0-based
listshow_Repeater.DataSource = pds;
listshow_Repeater.DataBind();
}
// 模擬資料存取
private DataTable GetDataTable(string sql)
{
// 實際專案請使用 OleDbConnection/OleDbDataAdapter
// 此處略過連線字串與參數化查詢
return new DataTable();
}
| 屬性 | 說明 |
|---|---|
DataSource | 接受 IEnumerable,通常傳 DataTable.DefaultView |
AllowPaging | 啟用分頁 |
PageSize | 每頁筆數 |
CurrentPageIndex | 0-based 目前頁索引 |
PageCount | 總頁數 (唯讀) |
DataSourceCount | 總筆數 (唯讀) |
PagedDataSource 屬於**記憶體分頁**:先將**所有資料**查出載入 DataTable,再切頁。資料量超過 5 萬筆時記憶體與速度明顯下降。解決方案:
OFFSET/FETCH,可用子查詢模擬:SELECT TOP pageSize * FROM (SELECT TOP (pageSize*pageIndex) * FROM Table ORDER BY Id) ORDER BY Id DESCHttpRuntime.Cache 快取完整 DataTable,依賴檔案變更或固定過期時間刷新。Pageing 設 AutoPostBack="True",使用者切換頁碼即自動回傳。Pagesize 文字方塊變更需手動觸發 DataBindGrid()(可加按鈕或 TextChanged 事件)。ViewState 自動保持。將上述 UI 與邏輯封裝為 Pager.ascx,暴露屬性 PageSize、CurrentPageIndex、事件 PageIndexChanged,任何頁面拖入即可使用,配合 ObjectDataSource 或自訂資料來源介面更靈活。
本文示範 ASP.NET 搭配 Access 使用 PagedDataSource 實作完整分頁功能,包含自訂分頁列 UI、按鈕/下拉列表導航、每頁筆數動態調整。理解記憶體分頁限制,並在資料增長時規劃 SQL 分頁或遷移策略,是系統長期穩定的關鍵。