基於 Request.QueryString 的輕量分頁控件,核心在於「當前頁、顯示按鈕數、總頁數」三者動態計算顯示區間。本文完整呈現屬性設計、區間演算法修正、HTML 渲染邏輯。
public int CurrentPageIndex { get; set; } = 0; // 當前頁(1-based)
public int PageSize { get; set; } = 16; // 每頁筆數
public int RowCount { get; set; } = 0; // 總筆數
public string PrevText { get; set; } = "上一頁";
public string NextText { get; set; } = "下一頁";
public string EllipsisText { get; set; } = "...";
public int EdgeEntries { get; set; } = 2; // 邊緣頁碼數
public bool PrevShowAlways { get; set; } = true;
public bool NextShowAlways { get; set; } = true;
public int DisplayEntries { get; set; } = 5; // 顯示按鈕總數
public string Url { get; set; } // 基礎 URL(含其他查詢參數)
public int NumPages() => (int)Math.Ceiling((decimal)RowCount / PageSize);
初版使用 Math.Ceiling(DisplayEntries / 2) 導致奇偶數 DisplayEntries 產生相同半徑,造成按鈕數量偏差。修正版區分奇偶:
public int[] GetInterval() {
int half = (int)Math.Ceiling((decimal)DisplayEntries / 2);
int pageCount = NumPages();
int upperLimit = pageCount - DisplayEntries;
int start, end;
if (DisplayEntries % 2 == 0) { // 偶數
start = CurrentPageIndex > half
? Math.Max(Math.Min(CurrentPageIndex - half, upperLimit), 1)
: 1;
} else { // 奇數
start = CurrentPageIndex > half
? Math.Max(Math.Min(CurrentPageIndex - half + 1, upperLimit), 1)
: 1;
}
end = CurrentPageIndex > half
? Math.Min(CurrentPageIndex + half - 1, pageCount)
: Math.Min(DisplayEntries, pageCount);
return new[] { start, end };
}
public string AppendItem(int pageId, string text) {
int id = pageId < 1 ? 1 : (pageId > PageCount ? PageCount : pageId);
return id == CurrentPageIndex
? $"{text}"
: $"{text}";
}
public string DrawLink() {
var interval = GetInterval();
var sb = new StringBuilder();
// 上一頁
if (!string.IsNullOrEmpty(PrevText) && CurrentPageIndex > 1 && PrevShowAlways)
sb.Append(AppendItem(CurrentPageIndex - 1, PrevText));
// 左邊緣頁碼 + 省略號
if (interval[0] > 1 && EdgeEntries > 0) {
int end = Math.Min(EdgeEntries, interval[0]);
bool adjacent = EdgeEntries == interval[0];
for (int i = 1; i <= (adjacent ? end - 1 : end); i++)
sb.Append(AppendItem(i, i.ToString()));
if (EdgeEntries + 1 < interval[0] && !string.IsNullOrEmpty(EllipsisText))
sb.Append($"{EllipsisText}");
}
// 主要頁碼區間
for (int i = interval[0]; i <= interval[1]; i++)
sb.Append(AppendItem(i, i.ToString()));
// 右邊緣頁碼 + 省略號
if (interval[1] < PageCount && EdgeEntries > 0) {
if (PageCount - EdgeEntries > interval[1] && !string.IsNullOrEmpty(EllipsisText))
sb.Append($"{EllipsisText}");
int begin = Math.Max(PageCount - EdgeEntries + 1, interval[1]);
bool adjacent = PageCount - EdgeEntries + 1 == interval[1];
for (int i = adjacent ? begin + 1 : begin; i <= PageCount; i++)
sb.Append(AppendItem(i, i.ToString()));
}
// 下一頁
if (!string.IsNullOrEmpty(NextText) && CurrentPageIndex < PageCount && NextShowAlways)
sb.Append(AppendItem(CurrentPageIndex + 1, NextText));
return sb.ToString();
}
分頁控件看似簡單,區間計算卻暗藏奇偶陷阱。掌握「半徑修正、邊界夾擠、省略號判斷」三大邏輯,即可實作出穩健且可配置的分頁元件。