自行指派 GridView.DataSource 並 DataBind() 時,首頁正常,翻頁即報錯。原因:GridView 翻頁會觸發 PageIndexChanging 事件,**開發者必須在事件處理器中重新設定 DataSource 並 DataBind**,否則 GridView 失去資料來源而異常。
<asp:GridView ID="GridView1" runat="server"
AllowPaging="true"
OnPageIndexChanging="GridView1_PageIndexChanging"
PageSize="10">
</asp:GridView>
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataSource = GetDataSource(); // 重新取得/建構資料來源
GridView1.DataBind();
}
// 範例:取得資料來源方法
private DataTable GetDataSource()
{
// 實際專案從 DB/快取/Session 取得
return (DataTable)ViewState["GridData"] ?? FetchFromDatabase();
}
private DataTable FetchFromDatabase()
{
var dt = new DataTable();
// ... 填充資料 ...
ViewState["GridData"] = dt; // 可選:暫存減少 DB 查詢
return dt;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = GetDataSource();
GridView1.DataBind();
}
}
PageIndex、PageSize、SortExpression 等分頁/排序狀態。SqlDataSource/ObjectDataSource 等資料源控制項時,框架自動處理,故不會遇到此問題。Session、MemoryCache、Redis。EnableViewState="false" 於 GridView 與頁面,僅保留必要控制項狀態。ListView + DataPager 或前端分頁(AJAX + WebAPI),徹底移除 ViewState 依賴。| 錯誤訊息 | 原因 | 解決 |
|---|---|---|
| 「必須在 GridView 控制項的 PageIndexChanging 事件中處理分頁作業」 | 同本文主錯誤 | 實作 OnPageIndexChanging 並重新 DataBind |
| 「索引超出範圍」 | PageIndex 超過實際頁數 | DataBind 前檢查 e.NewPageIndex < PageCount |
| 「資料來源為 null」 | GetDataSource 回傳 null | 確保回傳空 DataTable 而非 null |
GridView 手動繫結資料時,**翻頁 = PostBack = 重新繫結**。牢記「PageIndexChanging 事件中:更新 PageIndex → 重設 DataSource → DataBind」三步驟,即可徹底解決分頁異常。長期專案建議逐步遷移至前端分頁架構,減少伺服器狀態與 ViewState 負擔。