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

.NET 反射動態建立控件:從字串到實例的完整實作

     編輯:關於.NET

核心原理:Type.GetType 與 Activator.CreateInstance

.NET 反射機制允許在運行時根據完整型別名稱(含命名空間、組件資訊)動態載入型別並建立實例。關鍵在於取得正確的 AssemblyQualifiedName。

完整實作代碼

using System;
using System.Windows.Forms;
using System.Reflection;

public static class ControlFactory
{
    /// 
    /// 根據型別名稱動態建立控件並加入表單
    /// 
    /// 完整型別名,如 "System.Windows.Forms.TextBox"
    /// 目標表單
    /// X 座標
    /// Y 座標
    public static Control CreateControl(string controlType, Form form, int x, int y)
    {
        try
        {
            // 1. 取得 Windows Forms 組件完整限定名稱後綴
            string assemblyQualifiedName = typeof(Form).AssemblyQualifiedName;
            string assemblyInfo = assemblyQualifiedName.Substring(assemblyQualifiedName.IndexOf(','));

            // 2. 組合完整型別名稱:TypeName, AssemblyInfo
            string fullTypeName = controlType + assemblyInfo;

            // 3. 取得 Type 物件
            Type type = Type.GetType(fullTypeName);
            if (type == null)
                throw new ArgumentException($"找不到型別: {controlType}");

            // 4. 建立實例
            Control ctrl = (Control)Activator.CreateInstance(type);

            // 5. 初始化屬性並加入表單
            form.SuspendLayout();
            ctrl.Location = new System.Drawing.Point(x, y);
            ctrl.Name = type.Name + form.Controls.Count;
            form.Controls.Add(ctrl);
            form.ResumeLayout();

            return ctrl;
        }
        catch (Exception ex)
        {
            // 實務上應記錄日誌並拋出自訂異常
            throw new InvalidOperationException($"動態建立控件失敗: {controlType}", ex);
        }
    }
}

呼叫範例

// 在表單按鈕點擊事件中
private void btnCreate_Click(object sender, EventArgs e)
{
    // 動態建立 TextBox
    ControlFactory.CreateControl("System.Windows.Forms.TextBox", this, 10, 10);

    // 動態建立 Button
    ControlFactory.CreateControl("System.Windows.Forms.Button", this, 10, 50);

    // 動態建立 DataGridView
    ControlFactory.CreateControl("System.Windows.Forms.DataGridView", this, 10, 100);
}

關鍵技術細節解析

為什麼需要 AssemblyQualifiedName?

Type.GetType("System.Windows.Forms.TextBox") 會回傳 null,因為 System.Windows.Forms.dll 是強命名組件,存在 GAC 中有多版本。CLR 需完整組件資訊(版本、公開金鑰權杖、文化特性)才能精確載入。

通用取得組件資訊技巧

利用專案中已引用的任一 WinForms 型別(如 typeof(Form))取得其 AssemblyQualifiedName,截取逗號後的組件資訊,拼接至目標型別名稱。此法適用於同組件內所有控件。

擴充建議

  • 屬性注入:支援 Dictionary<string, object> 設定控件屬性(Text、Size、Font 等)。
  • 事件綁定:透過反射 GetEvent / AddEventHandler 動態掛載事件。
  • 配置驅動:從 XML/JSON 讀取控件定義,實現動態表單生成器。
  • 快取 Type:靜態 Dictionary<string, Type> 快取已解析型別,提升效能。

應用場景

  • 動態報表/表單設計器
  • 外掛/模組系統載入自訂控件
  • 依使用者權限動態顯示 UI 元素
  • 測試工具自動化生成介面

總結

反射動態建立控件是 .NET 靈活性的經典展現。掌握 AssemblyQualifiedName 組合技巧與 Activator.CreateInstance 流程,即可打破編譯期型別綁定限制,構建高度動態的應用程式。

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