GridView 內建分頁機制會在換頁時重新繫結資料,導致使用者在前一頁勾選的 CheckBox 狀態遺失。本文提供一套以 Session 為儲存媒介的完整解決方案,支援多頁面跨分頁保持選取狀態,並示範如何在「全選/取消」與「確定送出」時正確同步。
RememberOldValues() — 記住目前頁面的勾選狀態private void RememberOldValues()
{
ArrayList idList = new ArrayList();
// 若 Session 已有資料,先取出
if (Session["id"] != null)
idList = (ArrayList)Session["id"];
foreach (GridViewRow row in gridView.Rows)
{
string key = gridView.DataKeys[row.RowIndex].Value.ToString();
bool isChecked = ((CheckBox)row.FindControl("DeleteThis")).Checked;
if (isChecked)
{
if (!idList.Contains(key)) idList.Add(key);
}
else
{
idList.Remove(key);
}
}
if (idList.Count > 0) Session["id"] = idList;
else Session.Remove("id");
}
RePopulateValues() — 還原已勾選的列private void RePopulateValues()
{
if (Session["id"] == null) return;
ArrayList idList = (ArrayList)Session["id"];
foreach (GridViewRow row in gridView.Rows)
{
string key = gridView.DataKeys[row.RowIndex].Value.ToString();
if (idList.Contains(key))
{
CheckBox cb = (CheckBox)row.FindControl("DeleteThis");
cb.Checked = true;
}
}
}
protected void gridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
RememberOldValues(); // 1. 先存目前頁選取
gridView.PageIndex = e.NewPageIndex;
BindData(); // 2. 重新繫結資料
RePopulateValues(); // 3. 還原新頁面的選取
}
protected void btnSelect_Click(object sender, EventArgs e)
{
// 先同步當前頁面的勾選變化
RememberOldValues();
ArrayList idList = Session["id"] as ArrayList;
if (idList != null && idList.Count > 0)
{
string ids = string.Join(",", idList.ToArray());
// 呼叫前端 JS 回傳結果(示範用)
ScriptManager.RegisterStartupScript(this, GetType(), "", $"check('{ids}');", true);
}
Session.Remove("id"); // 清理
}
GridView1_SelectedIds),避免多 GridView 互相干擾。BindData() 之前呼叫 RememberOldValues(),否則舊頁面的勾選會被覆蓋。ArrayList 可改用 List<string> 或 HashSet<string> 提升效能。同樣邏輯可套用至 ListView、Repeater 等支援分頁的資料控制項,只需調整「取得 Key」與「尋找 CheckBox」的方式即可。