首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

手寫 ASP.NET 分頁控件核心邏輯:按鈕區間計算與渲染完整實作

     編輯:關於.NET

前言

基於 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);

關鍵演算法:計算顯示區間 [start, end]

初版使用 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 };
}

單一按鈕 HTML 產生

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();
}

原始碼下載

Paginate.zip 完整專案

小結

分頁控件看似簡單,區間計算卻暗藏奇偶陷阱。掌握「半徑修正、邊界夾擠、省略號判斷」三大邏輯,即可實作出穩健且可配置的分頁元件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved