常見於電商分類頁:左側或上方為大分類,每個分類下再列出所屬產品。使用巢狀 Repeater 可輕鬆實現「主從關係」的資料呈現。
private DataTable dtCategory, dtProduct;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
dtCategory = GetCategoryTable();
dtProduct = GetProductTable();
rptCategoryList.DataSource = dtCategory;
rptCategoryList.DataBind();
}
}
// 外層 Repeater ItemDataBound:綁定內層產品
protected void rptCategoryList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var drv = (DataRowView)e.Item.DataItem;
var ltlTitle = (Literal)e.Item.FindControl("ltlTitle");
ltlTitle.Text = drv["CategoryTitle"].ToString();
var rptProductList = (Repeater)e.Item.FindControl("rptProductList");
int catId = Convert.ToInt32(drv["CategoryId"]);
rptProductList.DataSource = GetProductTable(catId); // 依分類過濾
rptProductList.DataBind();
}
}
// 內層 Repeater ItemDataBound:顯示產品名稱
protected void rptProductList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var drv = (DataRowView)e.Item.DataItem;
var ltlTitle = (Literal)e.Item.FindControl("ltlTitle");
ltlTitle.Text = drv["ProductTitle"].ToString();
}
}
// 依 CategoryId 過濾產品
private DataTable GetProductTable(int categoryId)
{
var dv = dtProduct.DefaultView;
dv.RowFilter = $"CategoryId = {categoryId}";
return dv.ToTable();
}
// 以下為測試資料產生方法
private DataTable GetCategoryTable() { /* 略 */ }
private DataTable GetProductTable() { /* 略 */ }
<asp:Repeater ID="rptCategoryList" runat="server" OnItemDataBound="rptCategoryList_ItemDataBound">
<ItemTemplate>
<div class="listBox">
<div class="title"><asp:Literal ID="ltlTitle" runat="server" /></div>
<div class="content">
<ul>
<asp:Repeater ID="rptProductList" runat="server" OnItemDataBound="rptProductList_ItemDataBound">
<ItemTemplate>
<li><asp:Literal ID="ltlTitle" runat="server" /></li>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
SqlDataSource 或 ORM 直接在資料庫端 JOIN 後再分組,減少記憶體中 DataView.RowFilter 的運算。ListView 或純 `