TreeView 是 ASP.NET WebForms 時代呈現階層資料的經典控件。本文透過一個「產品分類三層級」的完整範例,示範如何結合 PopulateOnDemand 實現節點按需載入,大幅降低首屏渲染負擔。
每層節點點擊展開時,才向資料庫查詢子節點,避免一次性載入龐大樹狀結構。
protected void TreeView_TreeNodePopulate(object sender, TreeNodeEventArgs e) {
if (e.Node.ChildNodes.Count == 0) {
switch (e.Node.Depth) {
case 0: PopulateCategories(e.Node); break;
case 1: PopulateProductType(e.Node); break;
case 2: PopulateProducts(e.Node); break;
}
}
}
void PopulateCategories(TreeNode node) {
DataTable dt = productType.GetListByFatherNode(); // ParentID=0
foreach (DataRow row in dt.Rows) {
TreeNode n = new TreeNode(
row["ProductTypeName"].ToString(),
row["ProductTypeID"].ToString(),
"", // 圖示 URL
"../WebProductList.aspx?productTypeIdOne=" + row["ProductTypeID"],
""
);
n.PopulateOnDemand = true;
n.SelectAction = TreeNodeSelectAction.Expand;
node.ChildNodes.Add(n);
}
node.Expanded = true;
}
void PopulateProductType(TreeNode node) {
QueryParam qp = new QueryParam();
qp.Add("ParentID", QueryParam.RELATION.EQ, node.Value);
DataTable dt = productType.GetListByBranchNode(qp);
foreach (DataRow row in dt.Rows) {
TreeNode n = new TreeNode(
row["ProductTypeName"].ToString(),
row["ProductTypeID"].ToString(),
"",
"../WebProductList.aspx?productTypeIdTwo=" + row["ProductTypeID"],
""
);
n.PopulateOnDemand = true;
n.SelectAction = TreeNodeSelectAction.Expand;
node.ChildNodes.Add(n);
}
node.Expanded = false;
}
void PopulateProducts(TreeNode node) {
QueryParam qp = new QueryParam();
qp.Add("ProductTypeItemID", QueryParam.RELATION.EQ, node.Value);
DataTable dt = product.GetList(qp);
foreach (DataRow row in dt.Rows) {
TreeNode n = new TreeNode(
row["ProductName"].ToString(),
row["ProductID"].ToString(),
"",
"../WebProductDetaile.aspx?productID=" + row["ProductID"],
""
);
n.PopulateOnDemand = true; // 若無更深層級可設 false
n.SelectAction = TreeNodeSelectAction.Expand;
node.ChildNodes.Add(n);
}
node.Expanded = false;
}
| 屬性 | 作用 |
|---|---|
PopulateOnDemand | true 觸發 TreeNodePopulate 事件,實現懶加載 |
SelectAction | Expand 點擊文字展開節點;Select 則觸發選中事件 |
NavigateUrl | 設定後點擊文字直接跳轉,SelectAction 需設為 None 避免衝突 |
ParentID、ProductTypeItemID 必建索引。HttpRuntime.Cache 或 Redis 快取,減少資料庫往返。