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

ASP.NET 動態載入使用者控制項:PlaceHolder 容器、BasePage 基類封裝、Session 保持狀態完整實作

     編輯:關於ASP.NET

前言

需求:使用者點擊「新增」按鈕 PostBack 後,動態建立使用者控制項實例並加入頁面,且跨 PostBack 保持狀態。解決方案:PlaceHolder 容器 + BasePage 基類封裝動態載入邏輯 + Session 保存控制項資訊。

核心設計

public class BasePage : System.Web.UI.Page
{
    private const string SESSION_CONTAINERS_KEY = "Controls_In_Container";
    private const string PATH_TO_CONTROL = "~/App_Controls/{0}";

    protected void AddControl(string controlName, string placeHolderId)
    {
        // 1. 從 Session 取得已加入控制項清單
        List<ControlInfo> controls = Session[SESSION_CONTAINERS_KEY] as List<ControlInfo> 
            ?? new List<ControlInfo>();

        // 2. 建立新控制項資訊
        controls.Add(new ControlInfo { ControlName = controlName, PlaceHolderId = placeHolderId });
        Session[SESSION_CONTAINERS_KEY] = controls;

        // 3. 立即載入並加入對應 PlaceHolder
        LoadControlToPlaceholder(controlName, placeHolderId);
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        // 頁面初始化時,從 Session 還原所有動態控制項
        RestoreDynamicControls();
    }

    private void RestoreDynamicControls()
    {
        var controls = Session[SESSION_CONTAINERS_KEY] as List<ControlInfo>;
        if (controls != null)
        {
            foreach (var info in controls)
            {
                LoadControlToPlaceholder(info.ControlName, info.PlaceHolderId);
            }
        }
    }

    private void LoadControlToPlaceholder(string controlName, string placeHolderId)
    {
        Control ctrl = LoadControl(string.Format(PATH_TO_CONTROL, controlName));
        PlaceHolder ph = FindControlRecursive(this, placeHolderId) as PlaceHolder;
        if (ph != null) ph.Controls.Add(ctrl);
    }

    // 遞迴尋找控制項(支援 MasterPage、命名容器)
    private Control FindControlRecursive(Control root, string id) { ... }
}

public class ControlInfo
{
    public string ControlName { get; set; }
    public string PlaceHolderId { get; set; }
}

使用方式

  1. 頁面繼承 BasePage。
  2. 頁面放置一或多個 <asp:PlaceHolder ID="ph1" runat="server" />。
  3. 按鈕事件呼叫 AddControl("MyUserControl.ascx", "ph1")。

關鍵點總結

  • 動態控制項必須在 OnInit 重建,否則 ViewState、事件無法正常運作。
  • Session 儲存控制項中繼資料(名稱、目標 PlaceHolder),而非控制項實例。
  • BasePage 封裝通用邏輯,所有需動態載入的頁面只需繼承即可。
  • 支援多個 PlaceHolder,彈性決定加入位置。

結語

此模式解決動態控制項生命週期與狀態保持難題,結構清晰、可重用,是 ASP.NET WebForm 開發常用進階技巧。

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