在前幾篇文章中,我們已經探討了 ASP.NET 控件樣式的基礎知識。今天我們將進入一個更進階的主題——復合控件。由於這個話題內容較多,我將分為上下兩篇來詳細講解,本文先從基本概念與呈現機制切入。
復合控件與使用者控件有許多相似之處,但兩者存在本質區別:使用者控件的副檔名為 .ascx,而復合控件編譯後會生成 .dll 組件,方便分發與重用。簡單來說,復合控件將多個現有的伺服器控件(如 Label、TextBox、Button 等)封裝在一起,組合成一個功能更豐富、靈活性更高的新控件。
在前幾篇教程中,我們通過重寫 Render 或 RenderContents 方法,使用 HtmlTextWriter 手動輸出 HTML 標籤。例如:
public override void Render(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");
writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
writer.RenderEndTag();
}
這種方式要求開發者同時處理標籤佈局(如 <td>)與實際呈現標籤(如 <input>),代碼較為繁瑣且難以維護。
復合控件採用「包含子控件」的模式:開發者在 CreateChildControls 方法中實例化並配置所需的子控件(如 Label、TextBox),然後將它們加入 Controls 集合。最終的 HTML 輸出由各個子控件自行完成,因為每個控件都繼承自 Control 類並已實現自己的呈現邏輯。

圖中 LabelTextBox1 為復合控件,內部包含 Label 與 TextBox 兩個子控件;而 LabelTextBox2 則是傳統手寫渲染的控件。兩者的呈現流程截然不同。
要讓復合控件正常工作,必須熟悉以下三個核心成員:
Controls 集合。CreateChildControls。典型實現模式如下:
protected override void CreateChildControls()
{
Controls.Clear();
// 1. 建立子控件
Label lbl = new Label { ID = "lblTitle", Text = "姓名:" };
TextBox txt = new TextBox { ID = "txtName" };
// 2. 加入集合
Controls.Add(lbl);
Controls.Add(txt);
ChildControlsCreated = true;
}
protected override void Render(HtmlTextWriter writer)
{
EnsureChildControls(); // 確保子控件就緒
base.Render(writer); // 由子控件各自輸出 HTML
}
下一篇我們將深入探討復合控件的狀態管理、事件冒泡、樣式整合以及設計時支援等進階主題,敬請期待。