首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# WinForms 動態載入 UserControl:反射實例化變數名對應控件類型

     編輯:程式設計綜合問答

需求:根據資料庫欄位值 (字串) 動態建立對應的 `UserControl` (如 `ctl_user`),加入 `Panel` 顯示。使用反射 `Assembly.CreateInstance` 依類別全名實例化。

核心代碼


// 假設命名空間為 MyApp.Controls
string controlTypeName = "MyApp.Controls.ctl_user"; // 可從資料庫讀取
Control ctl = Assembly.GetExecutingAssembly().CreateInstance(controlTypeName) as Control;
if (ctl != null) {
    ctl.Dock = DockStyle.Fill;
    panelMain.Controls.Add(ctl);
} else {
    MessageBox.Show("找不到控件類型: " + controlTypeName);
}

完整封裝方法


public void LoadControl(string typeName, Panel container) {
    container.Controls.Clear();
    try {
        // 支援 "ctl_user" 短名,自動補全命名空間
        string fullName = typeName.Contains(".") ? typeName : "MyApp.Controls." + typeName;
        Control ctl = Assembly.GetExecutingAssembly().CreateInstance(fullName) as Control;
        if (ctl == null) throw new Exception("類型不存在或非 Control");
        ctl.Dock = DockStyle.Fill;
        container.Controls.Add(ctl);
    } catch (Exception ex) {
        MessageBox.Show("動態載入失敗: " + ex.Message);
    }
}

// 使用
LoadControl("ctl_user", panelMain);           // 短名
LoadControl("MyApp.Controls.ctl_admin", panelMain); // 全名

關鍵點總結

要點說明
命名空間一致字串必須為「命名空間.類別名」,區分大小寫
類別繼承 ControlUserControl 間接繼承 Control,可直接轉型
Dock = Fill確保控件填滿容器 Panel
Clear 再 Add避免重複疊加舊控件
異常處理類型錯誤、缺少建構子、存取層級皆可能失敗

進階:依賴注入與生命週期

  • 若控件需服務 (資料庫、設定),建議建構子注入或屬性注入,而非靜態存取。
  • 切換控件時,舊控件 `Dispose()` 釋放資源 (事件解綁、計時器停止)。
  • 考慮使用 `Lazy` 緩存實例,避免頻繁建構銷毀。

替代方案:泛型方法 (編譯期類型安全)


public void LoadControl(Panel container) where T : Control, new() {
    container.Controls.Clear();
    var ctl = new T { Dock = DockStyle.Fill };
    container.Controls.Add(ctl);
}
// 使用:LoadControl(panelMain);

若類型在編譯期已知,泛型版本更安全、效能更高;僅在類型完全由執行期字串決定時用反射。

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