首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 動態建立控件完整指南:ViewState 維持、事件綁定、生命週期陷阱

     編輯:關於ASP.NET

ASP.NET 動態建立控件 (Dynamic Controls) 必須在 **每次 PostBack 時重建**,且在 **ViewState 載入前** 完成 (通常在 OnLoad 或 OnInit),否則事件不觸發、值不保留。本文示範標準模式與常見坑點。

標準模式:OnLoad 重建 + ViewState 旗標

public partial class DynamicControlsDemo : System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        CreateControls(); // 每次 PostBack 都要重建
    }

    protected void btnCreate_Click(object sender, EventArgs e)
    {
        ViewState["ControlsCreated"] = true;
        CreateControls();
    }

    void CreateControls()
    {
        if (ViewState["ControlsCreated"] == null) return; // 首次不建立

        for (int x = 0; x < 10; x++)
        {
            var row = new TableRow();
            for (int y = 0; y < 10; y++)
            {
                var cell = new TableCell();
                var btn = new Button
                {
                    Text = $"x={x}, y={y}",
                    ID = $"btn_{x}_{y}" // 必須給 ID,否則 ViewState 無法對應
                };
                btn.Click += Btn_Click;
                cell.Controls.Add(btn);
                row.Cells.Add(cell);
            }
            HolderTable.Rows.Add(row);
        }
    }

    void Btn_Click(object sender, EventArgs e)
    {
        var btn = (Button)sender;
        btn.BackColor = System.Drawing.Color.Red;
        Response.Write($"你點擊了:{btn.Text}");
    }

    protected void btnDisplay_Click(object sender, EventArgs e)
    {
        foreach (TableRow row in HolderTable.Rows)
            foreach (TableCell cell in row.Cells)
                if (cell.Controls[0] is Button btn)
                    Response.Write(btn.Text + " ");
    }
}

關鍵規則

規則說明
**ID 必須固定**動態控件跨 PostBack 需相同 ID 才能載入 ViewState/事件
**每次 PostBack 重建**在 OnLoad/OnInit 中無條件重建 (或依旗標)
**事件綁定在重建時**btn.Click += ... 必須在 CreateControls 內
**容器控件需 runat=server**Table, PlaceHolder, Panel 等皆可作為容器

常見陷阱

  • 只在 !IsPostBack 建立 → PostBack 後控件消失、事件不觸發。
  • ID 使用索引或隨機值 → ViewState 無法匹配、事件綁定失效。
  • 在 btnCreate_Click 後未重建 → 新控件無事件、無 ViewState。
  • 大量動態控件導致 ViewState 膨脹 → 改用 Client-Side Rendering (JS 模板) 或減少伺服器控件。

現代替代方案

  • Repeater/GridView/ListView + Template:宣告式繫結,框架自動處理重建。
  • Client-Side (JS/React/Vue):資料以 JSON 交互,UI 完全在瀏覽器渲染。
  • ASP.NET Core TagHelper / ViewComponent:伺服器端渲染片段,無 ViewState 概念。

理解動態控件生命週期,是 Web Forms 進階開發的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved