Page.Controls、Panel.Controls 等集合僅包含第一層子控制項。巢狀結構(GridView → Rows → Cells → TextBox、UserControl 內部控制項)若不遞迴,根本找不到深層節點。
// 僅能處理 Page 直屬或單層容器內的 TextBox
for (int i = 0; i < this.Controls.Count; i++) {
foreach (Control ctrl in Page.Controls[i].Controls) {
if (ctrl is TextBox txt) txt.Text = string.Empty;
}
}
⚠️ 缺陷:無法處理 FormView、Repeater、GridView、UserControl 等命名容器內的控制項。
///
/// 遞迴遍歷控制項樹,對所有 TextBox 執行動作
///
public void ClearAllTextBoxes(ControlCollection controls) {
foreach (Control ctrl in controls) {
if (ctrl is TextBox txt) {
txt.Text = string.Empty;
}
if (ctrl.HasControls()) {
ClearAllTextBoxes(ctrl.Controls); // 遞迴進入子樹
}
}
}
// 呼叫入口
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) ClearAllTextBoxes(Page.Controls);
}
///
/// 通用遞迴遍歷:尋找符合條件的控制項並執行動作
///
/// 目標控制項型別
/// 起始控制項集合
/// 對每個符合項執行的委派
/// 可選的額外過濾條件
public void ForEachControl(ControlCollection controls, Action action, Func predicate = null)
where T : Control {
foreach (Control ctrl in controls) {
if (ctrl is T target && (predicate == null || predicate(target))) {
action(target);
}
if (ctrl.HasControls()) {
ForEachControl(ctrl.Controls, action, predicate);
}
}
}
// 使用範例:清空所有 TextBox
ForEachControl(Page.Controls, txt => txt.Text = string.Empty);
// 使用範例:只清空 ID 以 "txtSearch" 開頭的 TextBox
ForEachControl(Page.Controls,
txt => txt.Text = string.Empty,
txt => txt.ID.StartsWith("txtSearch"));
// 使用範例:收集所有 DropDownList 並重新繫結
var dropdowns = new List();
ForEachControl(Page.Controls, ddl => dropdowns.Add(ddl));
foreach (var ddl in dropdowns) RebindDropdown(ddl);
ASP.NET 控制項實作 INamingContainer(GridView、Repeater、FormView、UserControl)會建立獨立的 NamingContainer 作用域。遞迴遍歷 Controls 集合天然穿透命名容器,無需額外處理,這比 Page.FindControl("id") 更強大,因為:
ClientID(含 ctl00$ContentPlaceHolder1$... 前綴)。StackOverflowException。List 扁平化結果,但需在 PreRender 後失效(動態控制項可能變更)。| 需求 | 推薦做法 |
|---|---|
| 單一已知 ID 查找 | Page.FindControl("id") 或 NamingContainer.FindControl("id") |
| 批次處理同型別控制項(清空、驗證、繫結) | 泛型遞迴 ForEachControl |
| 需依條件篩選(ID 前綴、CSS Class、自訂屬性) | 泛型遞迴 + predicate |
| 動態新增控制項後立即操作 | 在 PreRender 階段遍歷,確保控制項樹已建構完成 |
掌握遞迴遍歷控制項樹,是 ASP.NET Web Forms 開發者處理複雜頁面交互的基本功,亦是理解控制項樹架構的最佳切入點。