Repeater 是 ASP.NET 最輕量的資料繫結控制項,**完全不產生預設 HTML 結構**,給予開發者 100% 的標記輸出控制權。無 ViewState、無預設樣式、無內建編輯功能,純粹專注於「重複渲染模板」,是高效能、高客製化需求的首選。
<asp:Repeater ID="rptData" runat="server">
<HeaderTemplate> <!-- 整個清單渲染前一次 --> </HeaderTemplate>
<ItemTemplate> <!-- 每筆資料重複渲染 --> </ItemTemplate>
<AlternatingItemTemplate> <!-- 交替項目(偶數行) --> </AlternatingItemTemplate>
<SeparatorTemplate> <!-- 項目之間分隔 --> </SeparatorTemplate>
<FooterTemplate> <!-- 整個清單渲染後一次 --> </FooterTemplate>
</asp:Repeater>
<%@ Import Namespace="System.Data" %>
<script runat="server">
void Page_Load() {
if (!IsPostBack) {
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/App_Data/cdcatalog.xml"));
rptCatalog.DataSource = ds;
rptCatalog.DataBind();
}
}
</script>
<asp:Repeater ID="rptCatalog" runat="server">
<HeaderTemplate>
<table class="data-table">
<thead>
<tr>
<th>標題</th>
<th>藝人</th>
<th>國家</th>
<th>唱片公司</th>
<th>價格</th>
<th>年份</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("title") %></td>
<td><%# Eval("artist") %></td>
<td><%# Eval("country") %></td>
<td><%# Eval("company") %></td>
<td>$<%# Eval("price") %></td>
<td><%# Eval("year") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
<AlternatingItemTemplate>
<tr class="alt-row">
<td><%# Eval("title") %></td>
<td><%# Eval("artist") %></td>
<td><%# Eval("country") %></td>
<td><%# Eval("company") %></td>
<td>$<%# Eval("price") %></td>
<td><%# Eval("year") %></td>
</tr>
</AlternatingItemTemplate>
CSS:.alt-row { background-color: #f2f2f2; }
Repeater 獨有的 SeparatorTemplate 在每兩個 ItemTemplate 之間渲染,不包含 Header/Footer:
<SeparatorTemplate>
<tr><td colspan="6"><hr class="separator" /></td></tr>
</SeparatorTemplate>
<ItemTemplate>
<div class="card">
<h3><%# Eval("title") %></h3>
<p><%# Eval("artist") %></p>
</div>
</ItemTemplate>
<SeparatorTemplate>
<div class="card-divider"></div>
</SeparatorTemplate>
<SeparatorTemplate>
<script>dataSections.push('<%# Container.ItemIndex %>');</script>
</SeparatorTemplate>
典型場景:分類清單 → 每個分類下的產品清單
<catalog>
<category name="Rock">
<cd><title>...</title></cd>
<cd><title>...</title></cd>
</category>
<category name="Pop">
<cd><title>...</title></cd>
</category>
</catalog>
<asp:Repeater ID="rptCategories" runat="server">
<ItemTemplate>
<h2><%# Eval("@name") %></h2>
<!-- 內層 Repeater 繫結該分類下的 CD -->
<asp:Repeater ID="rptCDs" runat="server"
DataSource='<%# XPathSelect("cd") %>'>
<HeaderTemplate><ul></HeaderTemplate>
<ItemTemplate>
<li><%# XPath("title") %> - <%# XPath("artist") %></li>
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
<asp:XmlDataSource ID="xdsCatalog" runat="server"
DataFile="~/App_Data/cdcatalog_nested.xml"
XPath="catalog/category" />
<asp:Repeater ID="rptCategories" runat="server" DataSourceID="xdsCatalog">
<ItemTemplate>
<h2><%# XPath("@name") %></h2>
<asp:Repeater ID="rptCDs" runat="server" DataSource='<%# XPathSelect("cd") %>'>
<!-- 模板定義 -->
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
| 指標 | Repeater | DataList | GridView |
|---|---|---|---|
| ViewState 大小 | 極小(無預設控制項狀態) | 中等 | 大(保留排序、分頁、編輯狀態) |
| 渲染速度 | 最快 | 快 | 較慢 |
| 記憶體佔用 | 最低 | 中等 | 最高 |
| 適合資料量 | 大量(千筆以上) | 中量 | 中小量(配合分頁) |
ItemDataBound 事件<%@ Page EnableViewState="false" %> 或控制項層級 EnableViewState="false"Eval() 而非 DataBinder.Eval()(內部已優化)<%@ OutputCache Duration="60" VaryByParam="none" %><asp:Repeater ID="rptCatalog" runat="server" OnItemDataBound="rptCatalog_ItemDataBound">
<ItemTemplate>
<tr>
<td><asp:Literal ID="litTitle" runat="server" /></td>
<td><%# Eval("artist") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
<script runat="server">
void rptCatalog_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
DataRowView drv = (DataRowView)e.Item.DataItem;
Literal lit = (Literal)e.Item.FindControl("litTitle");
string title = drv["title"].ToString();
// 依條件動態調整輸出
if (title.Length > 20) {
lit.Text = title.Substring(0, 20) + "...";
} else {
lit.Text = title;
}
// 依價格設定樣式
decimal price = Convert.ToDecimal(drv["price"]);
if (price > 15) {
e.Item.FindControl("litTitle").Controls.Clear();
lit.Text = "<strong>" + lit.Text + "</strong>";
}
}
}
</script>
Repeater 以極簡架構提供最大彈性,是追求效能與前端控制權的專業開發者利器。下一節將介紹 XML 資料直接繫結至清單控制項的簡化寫法。