Repeater 控件本身不支援客戶端排序,它只按數據源順序渲染。要將特定項目(如「待定」)移至最後,必須在綁定前對數據源排序,或在數據庫查詢時用 ORDER BY CASE 邏輯排序。
-- SQL Server
SELECT * FROM YourTable
ORDER BY
CASE WHEN Status = '待定' THEN 1 ELSE 0 END, -- 待定排最後
SortColumn ASC; -- 其他按正常順序
DataTable dt = GetData(); // 獲取原始數據
DataView dv = dt.DefaultView;
// 方式 1:RowFilter + Sort (簡單)
dv.Sort = "CASE WHEN Status = '待定' THEN 1 ELSE 0 END, SortColumn";
repeater.DataSource = dv;
repeater.DataBind();
// 方式 2:LINQ 排序後轉 DataTable (類型安全)
var sorted = dt.AsEnumerable()
.OrderBy(row => row.Field("Status") == "待定" ? 1 : 0)
.ThenBy(row => row.Field("SortColumn"))
.CopyToDataTable();
repeater.DataSource = sorted;
repeater.DataBind();
雖可在 ItemDataBound 中判斷並操作控件可見性,但會產生空白佔位、分頁計數錯誤、無障礙問題,屬於「治標不治本」。
<asp:Repeater ID="repData" runat="server">
<HeaderTemplate>
<ul class="data-list">
</HeaderTemplate>
<ItemTemplate>
<li>
<span class="status"><%# Eval("Status") %></span>:
<span class="content"><%# Eval("Data") %></span>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
BindData();
}
}
private void BindData() {
DataTable dt = GetDataFromDatabase(); // 假設含 Status, Data, SortColumn 列
// 核心:綁定前排序
DataView dv = dt.DefaultView;
dv.Sort = "CASE WHEN Status = '待定' THEN 1 ELSE 0 END, SortColumn ASC";
repData.DataSource = dv;
repData.DataBind();
}
public static class DataViewExtensions {
public static DataView SortWithCustomLogic(this DataView dv, string columnName, string lastValue) {
// 動態構建 CASE WHEN 排序表達式
string sortExpr = $"CASE WHEN {columnName} = '{lastValue}' THEN 1 ELSE 0 END, {columnName}";
dv.Sort = sortExpr;
return dv;
}
}
// 使用
dv.SortWithCustomLogic("Status", "待定");
掌握「數據源排序」而非「控件排序」的思維,是從頁面開發者進階為數據驅動開發者的關鍵。