• DynamicCreateMenu (反射调用Form)


    //创建主菜单
            private void CreateMenus()
            {
                MenuStrip mainMenu 
    = new MenuStrip();
                DataSet ds 
    = new DataSet();
                
    string xmlMenuIndo = System.Windows.Forms.Application.StartupPath;//应用程序运行路径Debug下
                ds.ReadXml(xmlMenuIndo + @"\sy_menu_wds.xml");
                DataView dv 
    = ds.Tables[0].DefaultView;
                dv.RowFilter 
    = "ParentID=-1";
                
    for (int i = 0; i < dv.Count; i++)
                {
                    ToolStripMenuItem subMenuItem 
    = new ToolStripMenuItem();
                    subMenuItem.Text 
    = dv[i]["title"].ToString();

                    
    if (Convert.ToInt16(dv[i]["IsChild"]) == 1)
                    {
                        
    //以ref的方式将顶层菜单传递参数,因为他可以在赋值后再回传。
                        CreateSubMenuItem(ref subMenuItem, Convert.ToInt32(dv[i]["ID"]), ds.Tables[0]);
                    }
                    mainMenu.MdiWindowListItem 
    = subMenuItem;
                    mainMenu.Items.Add(subMenuItem);
                }
                mainMenu.Dock 
    = DockStyle.Top;
                
    this.MainMenuStrip = mainMenu; //将窗体的MainMenuStrip梆定为mainMenu.
                this.Controls.Add(mainMenu);  
            }

            
    //创建子菜单
            private void CreateSubMenuItem(ref ToolStripMenuItem subMenuItem, int ID, DataTable dt)
            {
                DataView dv 
    = new DataView(dt);
                dv.RowFilter 
    = "ParentID="+ID.ToString().Trim();
                
    for (int i = 0; i < dv.Count; i++)
                {
                    ToolStripMenuItem sMenuItem
    =new ToolStripMenuItem();
                    sMenuItem.Text 
    = dv[i]["Title"].ToString();
                    
    if (Convert.ToInt16(dv[i]["IsChild"]) == 1)
                    {
                        CreateSubMenuItem(
    ref sMenuItem, Convert.ToInt32(dv[i]["ID"]), dt);
                    }
                    
    else if ("数据备份".Equals(dv[i]["Title"].ToString()))
                    {
                        sMenuItem.Tag 
    = "BACKUP";
                        sMenuItem.Click
    +=new EventHandler(OtherTools_Click);
                    }
                    
    else if ("退出系统".Equals(dv[i]["Title"].ToString()))
                    {
                        sMenuItem.Click 
    += new EventHandler(ExitMenuItem_Click);
                    }
                    
    else //没有子菜单,则创建窗体实例
                    {
                        sMenuItem.Tag 
    = dv[i]["FrmName"].ToString();
                        sMenuItem.Click 
    += new EventHandler(sMenuItem_Click);
                    }
                    subMenuItem.DropDownItems.Add(sMenuItem); 
    //将菜单加到顶层菜单下
                }
            }

            
    ////菜单单击事件
            void sMenuItem_Click(object sender, EventArgs e)
            {
                
    string frmName = ((ToolStripMenuItem)sender).Tag.ToString();
                CreateFormInstance(frmName);
    //创建显示窗体
            }

            
    ////创建form实例以显示窗体
            private void CreateFormInstance(string formName)
            {
                
    bool blflag = false;
                
    for (int i = 0; i < this.MdiChildren.Length; i++//若窗体已经打开,则重新激活并打开
                {
                    
    if (this.MdiChildren[i].Tag.ToString().ToLower() == formName.ToLower())
                    {
                        
    this.MdiChildren[i].Activate();
                        
    this.MdiChildren[i].Show();
                        
    this.MdiChildren[i].WindowState = FormWindowState.Normal;
                        blflag 
    = true;
                        
    break;
                    }
                }
                
    if (!blflag)
                {
                    
    //利用反射动态生成窗体
                    string path = System.Windows.Forms.Application.StartupPath;
                    
    string dllName = formName.Substring(0, formName.IndexOf("."))+".dll"//得到DLL文件名(Test.dll)
                    Assembly assembly = Assembly.LoadFrom(path + @"\"+dllName+"");
                    Type t 
    = assembly.GetType(formName);//必须是:命名空间.窗体类名(Test.Frm1)
                    object obj = Activator.CreateInstance(t);
                    Form frm 
    = (Form)obj;
                    frm.Tag 
    = formName.ToString().Trim();//tag属性要重新写一次,否则在第二次的时候取不到
                    frm.MdiParent = this;
                    frm.Show();
                }
            }

            
    private void OtherTools_Click(object sender, EventArgs e)
            {
                
    switch (((ToolStripMenuItem)(sender)).Tag.ToString().Trim())
                {
                    
    case "BACKUP":
                        {
                            Tools.DataBack();
                            
    break;
                        }
                }
            }


    //===========================================//
    //利用.Net自身提供的类对象(例如Form对象、Control对象)利用反射动态创建窗体对象

        
    //利用反射动态创建窗体对象:事实上就是通过Assembly动态加载DLL
         private void CreateFormInstance(string formName)
            {
            
    string str = System.Windows.Forms.Application.StartupPath;
                    Assembly assembly 
    = Assembly.LoadFrom(str+@"\Test.dll");
                    Type t 
    = assembly.GetType(formName); //formName一定要是[命名空间.窗体名]
                    object obj = Activator.CreateInstance(t);
                    Form frm 
    = (Form)obj;
                    frm.MdiParent 
    = this;
                    frm.Show();
            }

    //代码说明:
    1)首先是通过Assembly.LoadFrom()来加载dll文件;
    2)再通过GetType()来获得要创建的Form类对象的类型。注意,在GetType()方法的参数为类型的名字,为string类型,同时该名字应为类型的FullName,即:命名空间名.类名;
    3)然后通过Activator.CreateInstance()方法创建该类型对象,返回object对象。
    4)再将该对象强制转换为Form类型。
    5)最后调用即可。
    //结论:对于.Net自身提供的类对象,我们对它直接强制转换即可。不会出现任何问题。
    //===========================================//



    //===========================================//
    //利用自定义对象通过反射动态创建自定义对象(如:窗体对象)
    //动态加载的Dll和手工添加的dll引用,系统会认为不是同一个Assembly。解决方法:应该使用接口
    1、创建一个接口AutoObjectInterface.IAutoObject,该接口包括要加载对象类的方法、属性(AutoObjectInterface.dll)
    2、创建自定义类对象:AutoObject.TestObject(AutoObject.dll) 实现了1中的接口
    3、利用反射动态创建该对象:
            {
                
    string str = System.Windows.Forms.Application.StartupPath;
            Assembly assembly 
    = Assembly.LoadFrom(str+@"\AutoObject.dll");
                Type type 
    = assembly.GetType("AutoObject.TestObject");

                
    object obj = Activator.CreateInstance(type);
                
    //因为是自定义对象,所以我们不知道将其转换成什么对象,所以要添加接口的引用,转换的时候就转换为接口的类型了
                AutoObjectInterface.IAutoObject iObj = (AutoObjectInterface.IAutoObject)obj; 
               
                iObj.方法();
                }
    //这样我们就可以通过接口对象实例来调用类对象的方法

    //结论:在通过反射动态创建对象时,一定要注意区别所创建对象的类型。如果是自定义对象,必须通过单独的接口,来进行类型的转换。
    //===========================================//


    string path = System.Windows.Forms.Application.StartupPath;
    string dllName = formName.Substring(0, formName.IndexOf("."))+".dll";
    Assembly assembly 
    = Assembly.LoadFrom(path + @"\"+dllName+"");
  • 相关阅读:
    ACM-ICPC 2018 徐州赛区网络预赛 D 杜教筛 前缀和
    51 Nod 1244 莫比乌斯函数前n项和
    20170914-构建之法:现代软件工程-阅读笔记
    结对-五子棋游戏-开发环境搭建过程
    结对-五子棋游戏-设计文档
    Git使用方法2.0
    团队-象棋游戏-团队信息
    Web开发技术——JQuery4(隐藏和显示、淡入和淡出、滑动)
    Web开发技术——JQuery3(事件)
    Web开发技术——JQuery2(语法和选择器)
  • 原文地址:https://www.cnblogs.com/inspurhaitian/p/1256674.html
Copyright © 2020-2023  润新知