ASP.NET 動態新增伺服器控件(而非 HTML 標籤)時,最大挑戰在於 PostBack 後能正確重建控件樹並取得使用者輸入值。本文透過完整範例,示範動態產生 Url 輸入欄位、驗證與取值的最佳實踐。
<style type="text/css">
.item { margin:10px; border-bottom:solid 1px #CCC; }
.item2 { margin:5px; }
.input { width:200px; }
</style>
Page_Init 階段重建,確保 ViewState 正確載入與事件觸發。txtUrl_0, txtUrl_1),否則 PostBack 時無法對應 ViewState。Response.Write。public partial class DynamicControlsDemo : System.Web.UI.Page
{
private const string UrlCountKey = "DynamicUrlCount";
private int UrlCount
{
get { return ViewState[UrlCountKey] != null ? (int)ViewState[UrlCountKey] : 0; }
set { ViewState[UrlCountKey] = value; }
}
protected void Page_Init(object sender, EventArgs e)
{
// 重建動態控件
for (int i = 0; i < UrlCount; i++)
CreateUrlInputRow(i);
}
protected void btnGenerate_Click(object sender, EventArgs e)
{
if (int.TryParse(txtCount.Text, out int count) && count > 0 && count <= 20)
{
UrlCount = count;
phUrls.Controls.Clear();
for (int i = 0; i < count; i++)
CreateUrlInputRow(i);
}
}
private void CreateUrlInputRow(int index)
{
var itemDiv = new HtmlGenericControl("div") { Attributes = { ["class"] = "item" } };
var lbl = new Label { Text = $"Url {index + 1}: ", AssociatedControlID = $"txtUrl_{index}" };
var txt = new TextBox { ID = $"txtUrl_{index}", CssClass = "input" };
var val = new RegularExpressionValidator
{
ControlToValidate = txt.ID,
ValidationExpression = @"^https?://[^\s/$.?#].[^\s]*$",
ErrorMessage = "Url 格式錯誤",
CssClass = "error",
Display = ValidatorDisplay.Dynamic
};
itemDiv.Controls.Add(lbl);
itemDiv.Controls.Add(txt);
itemDiv.Controls.Add(val);
phUrls.Controls.Add(itemDiv);
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
var results = new List<string>();
for (int i = 0; i < UrlCount; i++)
{
var txt = phUrls.FindControl($"txtUrl_{i}") as TextBox;
if (txt != null)
results.Add($"Url {i+1}: {txt.Text}");
}
litResult.Text = string.Join("<br/>", results);
}
}
<asp:TextBox ID="txtCount" runat="server" />
<asp:Button ID="btnGenerate" Text="產生輸入框" OnClick="btnGenerate_Click" runat="server" />
<asp:PlaceHolder ID="phUrls" runat="server" />
<asp:Button ID="btnSubmit" Text="提交" OnClick="btnSubmit_Click" runat="server" />
<asp:Literal ID="litResult" runat="server" />
Page_Load 建立動態控件 → ViewState 不會載入,事件不觸發。Add → 重複控件導致例外。ControlToValidate 指向正確 ID。