C#实现从dll程序集中动态加载窗体

50 篇文章 1 订阅
47 篇文章 0 订阅

http://www.csharpwin.com/csharpspace/10879r957.shtml


昨天晚上花了一晚上时间写了一个从程序集中动态加载窗体的程序.将任何包含窗体的代码编译成 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 窗体设计器生成的代码 #region Windows 窗体设计器生成的代码 /**/ /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this .mnuMain = new System.Windows.Forms.MainMenu(); this .mnuItmRun = new System.Windows.Forms.MenuItem(); this .mnuItemWindow = new System.Windows.Forms.MenuItem(); this .mnuItmCascade = new System.Windows.Forms.MenuItem(); this .mnuItmTileHorizontal = new System.Windows.Forms.MenuItem(); this .mnuItmTileVertical = new System.Windows.Forms.MenuItem(); this .menuItem1 = new System.Windows.Forms.MenuItem(); this .mnuItmHelp = new System.Windows.Forms.MenuItem(); this .mnuItmAbout = new System.Windows.Forms.MenuItem(); this .staBarMain = new System.Windows.Forms.StatusBar(); this .pnlInfo = new System.Windows.Forms.StatusBarPanel(); this .pnlNum = new System.Windows.Forms.StatusBarPanel(); ((System.ComponentModel.ISupportInitialize)( this .pnlInfo)).BeginInit(); ((System.ComponentModel.ISupportInitialize)( this .pnlNum)).BeginInit(); this .SuspendLayout(); // // mnuMain // this .mnuMain.MenuItems.AddRange( new System.Windows.Forms.MenuItem[] { this .mnuItmRun, this .mnuItemWindow, this .mnuItmHelp}); // // mnuItmRun // this .mnuItmRun.Index = 0 ; this .mnuItmRun.Text = " 运行窗体(&R) " ; // // mnuItemWindow // this .mnuItemWindow.Index = 1 ; this .mnuItemWindow.MenuItems.AddRange( new System.Windows.Forms.MenuItem[] { this .mnuItmCascade, this .mnuItmTileHorizontal, this .mnuItmTileVertical, this .menuItem1}); this .mnuItemWindow.Text = " 窗口(&W) " ; // // mnuItmCascade // this .mnuItmCascade.Index = 0 ; this .mnuItmCascade.Text = " 层叠窗口 " ; this .mnuItmCascade.Click += new System.EventHandler( this .mnuItmCascade_Click); // // mnuItmTileHorizontal // this .mnuItmTileHorizontal.Index = 1 ; this .mnuItmTileHorizontal.Text = " 横向平铺窗口 " ; this .mnuItmTileHorizontal.Click += new System.EventHandler( this .mnuItmTileHorizontal_Click); // // mnuItmTileVertical // this .mnuItmTileVertical.Index = 2 ; this .mnuItmTileVertical.Text = " 纵向平铺窗口 " ; this .mnuItmTileVertical.Click += new System.EventHandler( this .mnuItmTileVertical_Click); // // menuItem1 // this .menuItem1.Index = 3 ; this .menuItem1.Text = " - " ; // // mnuItmHelp // this .mnuItmHelp.Index = 2 ; this .mnuItmHelp.MenuItems.AddRange( new System.Windows.Forms.MenuItem[] { this .mnuItmAbout}); this .mnuItmHelp.Text = " 帮助(&H) " ; // // mnuItmAbout // this .mnuItmAbout.Index = 0 ; this .mnuItmAbout.Shortcut = System.Windows.Forms.Shortcut.F1; this .mnuItmAbout.Text = " 关于(&A) " ; this .mnuItmAbout.Click += new System.EventHandler( this .mnuItmAbout_Click); // // staBarMain // this .staBarMain.Location = new System.Drawing.Point( 0 , 343 ); this .staBarMain.Name = " staBarMain " ; this .staBarMain.Panels.AddRange( new System.Windows.Forms.StatusBarPanel[] { this .pnlInfo, this .pnlNum}); this .staBarMain.ShowPanels = true ; this .staBarMain.Size = new System.Drawing.Size( 584 , 22 ); this .staBarMain.TabIndex = 1 ; // // pnlInfo // this .pnlInfo.Width = 300 ; // // pnlNum // this .pnlNum.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring; this .pnlNum.Width = 268 ; // // FrmMain // this .AutoScaleBaseSize = new System.Drawing.Size( 6 , 14 ); this .ClientSize = new System.Drawing.Size( 584 , 365 ); this .Controls.Add( this .staBarMain); this .IsMdiContainer = true ; this .Menu = this .mnuMain; this .Name = " FrmMain " ; this .StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this .Text = " 动态加载窗体 " ; this .Load += new System.EventHandler( this .FrmMain_Load); ((System.ComponentModel.ISupportInitialize)( this .pnlInfo)).EndInit(); ((System.ComponentModel.ISupportInitialize)( this .pnlNum)).EndInit(); this .ResumeLayout( false ); } #endregion 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 ); } } }

   程序源码下载http://files.cnblogs.com/Infinity/WindowsForm.rar
  
  程序截图:

单个 dll 文件包含一个窗体时:

 
 

当程序目录下的所有程序集中包含一个窗体类时,程序运行界面:
 


 

多个 dll 文件包含多个窗体时:
 


 

当程序目录下的所有程序集中包含多个窗体类时,程序运行界面:
 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值