昨天晚上花了一晚上時間寫了一個從程式集中動態載入窗體的程式.將任何包含窗體的程式碼編譯成 dll 檔案,再把 dll 檔案拷貝到本程式的目錄下,本程式執行時即可動態檢查到 dll 檔案中的窗體,將窗體類的型別在程式選單中顯示出來,點選選單即可執行對應的窗體.
本程式主要用到了 Assembly 類動態載入程式集,再得到程式集中包含類的 Type 型別,動態生成類例項,動態呼叫類方法.個人覺得這是一種提供高度鬆耦合,可隨意擴充套件的程式結構框架,希望和大家探討一下這種框架的應用前景!
關鍵性程式碼如下:
using System; using System.Drawing; using System.IO; using System.Reflection; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace WindowsFormTest { /// <summary> /// Form1 的摘要說明。 /// </summary> public class FrmMain : System.Windows.Forms.Form { private int formNum; private ArrayList formTypes = new ArrayList(); private ArrayList formObjects = new ArrayList(); private System.Windows.Forms.MainMenu mnuMain; private System.Windows.Forms.MenuItem mnuItmRun; private System.Windows.Forms.MenuItem mnuItemWindow; private System.Windows.Forms.MenuItem mnuItmHelp; private System.Windows.Forms.MenuItem mnuItmCascade; private System.Windows.Forms.MenuItem mnuItmTileHorizontal; private System.Windows.Forms.MenuItem mnuItmTileVertical; private System.Windows.Forms.MenuItem menuItem1; private System.Windows.Forms.MenuItem mnuItmAbout; private System.Windows.Forms.StatusBar staBarMain; private System.Windows.Forms.StatusBarPanel pnlInfo; private System.Windows.Forms.StatusBarPanel pnlNum; /// <summary> /// 必需的設計器變數。 /// </summary> private System.ComponentModel.Container components = null; public FrmMain() { // // Windows 窗體設計器支援所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 呼叫後新增任何建構函式程式碼 // } /// <summary> /// 清理所有正在使用的資源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } Windows 窗體設計器生成的程式碼 private void FrmMain_Load(object sender, System.EventArgs e) { Assembly assembly = null; string windowsPath = Path.Combine(Application.StartupPath, "Windows"); foreach (string dllFile in Directory.GetFiles(windowsPath, "*.dll")) { assembly = Assembly.LoadFile(dllFile); Type[] types = assembly.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(Form)) { this.formTypes.Add(t); MenuItem item = this.mnuItmRun.MenuItems.Add(t.FullName); item.Click += new EventHandler(menuItemNewItem_Click); } } } } private void menuItemNewItem_Click(object sender, EventArgs e) { MenuItem item = (MenuItem)sender; Type t = (Type)(this.formTypes[item.Index]); Object obj = Activator.CreateInstance(t); this.formObjects.Add(obj); formNum += 1; t.InvokeMember("MdiParent", BindingFlags.SetProperty, null, obj, new object[] {this}); t.InvokeMember("Text", BindingFlags.SetProperty, null, obj, new object[] {t.FullName+" 窗體:"+formNum}); t.InvokeMember ("Show", BindingFlags.InvokeMethod, null, obj, new object [] {}); ((Form)obj).Closing += new CancelEventHandler(FrmWindow_Closing); ((Form)obj).Activated += new EventHandler(FrmWindow_Activated); MenuItem menuItem = this.mnuItemWindow.MenuItems.Add(((Form)obj).Text); menuItem.Click += new EventHandler(menuItemWindow_Click); this.pnlNum.Text = "當前裝載了"+this.formObjects.Count+"個窗體"; this.pnlInfo.Text = "當前活動窗體:"+this.ActiveMdiChild.Text; } private void menuItemWindow_Click(object sender, System.EventArgs e) { MenuItem item = (MenuItem)sender; ((Form)(this.formObjects[item.Index-4])).Activate(); this.pnlNum.Text = "當前裝載了"+this.formObjects.Count+"個窗體"; this.pnlInfo.Text = "當前活動窗體:"+this.ActiveMdiChild.Text; } private void FrmWindow_Activated(object sender, System.EventArgs e) { this.pnlNum.Text = "當前裝載了"+this.formObjects.Count+"個窗體"; this.pnlInfo.Text = "當前活動窗體:"+this.ActiveMdiChild.Text; } private void FrmWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { for (int i=0; i<this.formObjects.Count; i++) { if (((Form)this.formObjects[i]).Text == ((Form)sender).Text) { this.formObjects.RemoveAt(i); this.mnuItemWindow.MenuItems.RemoveAt(i+4); this.pnlNum.Text = "當前裝載了"+this.formObjects.Count+"個窗體"; this.pnlInfo.Text = "當前活動窗體:"+this.ActiveMdiChild.Text; break; } } } private void mnuItmCascade_Click(object sender, System.EventArgs e) { this.LayoutMdi(MdiLayout.Cascade); } private void mnuItmTileHorizontal_Click(object sender, System.EventArgs e) { this.LayoutMdi(MdiLayout.TileHorizontal); } private void mnuItmTileVertical_Click(object sender, System.EventArgs e) { this.LayoutMdi(MdiLayout.TileVertical); } private void mnuItmAbout_Click(object sender, System.EventArgs e) { new FrmAbout().ShowDialog(this); } } }
程式原始碼下載:/Files/Infinity/WindowsForm.rar
程式截圖
單個 dll 檔案包含一個窗體時:
當程式目錄下的所有程式集中包含一個窗體類時,程式執行介面:
多個 dll 檔案包含多個窗體時:
當程式目錄下的所有程式集中包含多個窗體類時,程式執行介面: