苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 84652|回复: 31
打印 上一主题 下一主题

[Winform] C#反射动态调用窗体,动态实例化窗体的方法

[复制链接]
跳转到指定楼层
楼主
发表于 2013-5-6 11:08:31 | 显示全部楼层 |只看大图 回帖奖励 |倒序浏览 |阅读模式
                  C#反射动态调用窗体,动态实例化窗体的方法

其实这个问题很简单只要我们使用一点点反射的原理就行了,
看下面的方法吧

单击那个按钮就会出现那个窗体,
如果非常多的按钮的话我们是不是一般会这样写
[C#] 纯文本查看 复制代码
private void button3_Click(object sender, EventArgs e)
        {
            //获取单击的Button名称
            string btnname = ((Button)sender).Name;
            if (btnname == "button1")
            {
                //处理窗体
            }
            else if (btnname == "button2")
            {
                //处理窗体
            }
            else
            {
                //处理窗体
            }
        }

这样也不是不可 行,但是如果100多个上千个就不行了,
可以说超过10个就不好玩了,但是如果使用反射就很方便 ,只需要几行代码就可以的,
看下面的方法吧
[C#] 纯文本查看 复制代码
  /// <summary>  
        /// 打开新的子窗体  
        /// </summary>  
        /// <param name="strName">窗体的类名</param>  
        /// <param name="AssemblyName">窗体所在类库的名称</param>   
        public static void CreateForm(string strName, string AssemblyName)
        {
            string path = AssemblyName;//项目的Assembly选项名称  
            string name = strName; //类的名字  
            Form doc = (Form)Assembly.Load(path).CreateInstance(name);
            doc.Show();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //获取单击的Button名称
            string btnname = ((Button)sender).Text;
            CreateForm("WindowsFormsApplication1." + btnname, "WindowsFormsApplication1");
        }

有了上面的方法,只要我们的用户控件Text和窗体的类名一样就可能实现动态加载了,当然如果有的同志说我的Text要用汉字怎么办,那就再换个属性啊,比如Name或者是其他属性都可以。总之肯定比你一个一个的去写要方便很多
 如果你是使用的子窗体的方式
而不是用户控件还可以使用下面方法判断是否已打开
下面的提供下代码
WindowsFormsApplication1.zip (51.76 KB, 下载次数: 2109)
不过大家需要先注册用户才能下载哦
如果你使用的子窗体的模式还可以使用下面的代码进行限制重复打开的
[C#] 纯文本查看 复制代码
/// <summary>  
        /// 打开新的子窗体  
        /// </summary>  
        /// <param name="strName">窗体的类名</param>  
        /// <param name="AssemblyName">窗体所在类库的名称</param>  
        /// <param name="MdiParentForm">父窗体</param>  
        public static void CreateForm(string strName, string AssemblyName, Form MdiParentForm)  
        {  
            int Index = strName.LastIndexOf(".");  
            string FormName = strName.Substring(23);  
            if (!ShowChildForm(FormName, MdiParentForm))  
            {  
                string path = AssemblyName;//项目的Assembly选项名称  
                string name = strName; //类的名字  
                Form doc = (Form)Assembly.Load(path).CreateInstance(name);  
                doc.WindowState = FormWindowState.Maximized;  
                doc.MdiParent = MdiParentForm;  
                doc.Show();  
            }  
        }  
  
        /// <summary>  
        /// 防止子窗体再度打开  
        /// </summary>  
        /// <param name="p_ChildrenFormText"></param>  
        /// <param name="MdiParentForm"></param>  
        /// <returns></returns>  
        public static bool ShowChildForm(string p_ChildrenFormText, Form MdiParentForm)  
        {  
            int i;  
            //依次检测当前窗体的子窗体  
            for (i = 0; i < MdiParentForm.MdiChildren.Length; i++)  
            {  
                //判断当前子窗体的Text属性值是否与传入的字符串值相同  
                if (MdiParentForm.MdiChildren.Name == p_ChildrenFormText)  
                {  
                    //如果值相同则表示此子窗体为想要调用的子窗体,激活此子窗体并返回true值  
                    MdiParentForm.MdiChildren.Activate();  
                    return true;  
                }  
            }  
            //如果没有相同的值则表示要调用的子窗体还没有被打开,返回false值  
            return false;  
        }  

好了,大家自己亲身下载测试下吧
需要带参数的方式可以看这个文章
http://www.sufeinet.com/thread-2190-1-1.html


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
沙发
 楼主| 发表于 2013-7-15 08:11:57 | 显示全部楼层
chenwu0815 发表于 2013-7-14 22:54
之前写了一个权限动态加载菜单,但是点击后,不能打开对应的FORM,还是手工添加的打开对应FORM的程序,明天 ...

我一直是这么用的,你要吧试试,应该没有问题,如有什么问题可以发帖子
板凳
 楼主| 发表于 2013-7-15 12:12:05 | 显示全部楼层
chenwu0815 发表于 2013-7-15 12:06
已经测试OK。。通过查询数据库中的权限对应的Form名称,直接打开对应Form。。感谢

不客气
地板
 楼主| 发表于 2013-8-19 12:47:08 | 显示全部楼层
chenwu0815 发表于 2013-8-19 11:52
现在在考虑传值的问题,需要将user的几个值传到打开后的FORM。。。

Form doc = (Form)Assembly.Load(path).CreateInstance(name);
doc就是窗体对象,直接调用里面的变量赋值就行了

            doc.Show();
5
 楼主| 发表于 2013-8-20 15:27:01 | 显示全部楼层
chenwu0815 发表于 2013-8-20 14:37
那我需要怎么修改程序来实现类似的传值呢?

Complaint()这应该是你的构造方法吧,你之前是通过构造方法来传值的,现在不要通过这个来传值就行了,
在Complaint里定义一下Public方法,调用传值来实现
6
 楼主| 发表于 2013-8-20 15:29:55 | 显示全部楼层
chenwu0815 发表于 2013-8-20 14:37
那我需要怎么修改程序来实现类似的传值呢?

http://www.sufeinet.com/thread-2190-1-1.html或者你看看我的这个文章,学习一下这种方法
7
 楼主| 发表于 2013-8-20 16:13:07 | 显示全部楼层
chenwu0815 发表于 2013-8-20 15:41
之前子窗体就用通过如下来获取的。

public Complaint(string username, string name, string branch, ...

把这个提取成一个Public方法就行了,安我楼上说的去做,
还有就是可以看楼上的文章直接通过反射处理

8
 楼主| 发表于 2013-8-21 11:16:22 | 显示全部楼层
chenwu0815 发表于 2013-8-21 11:12
private void GetUserInfo()
        {
            Assembly assembly = Assembly.Load("Improvemen ...

Public方法定义在子窗体,在主窗体得到对象之后直接调用就行了,就是一个方法,
类名.方法名
这样调用。
传值


你要不发个新的帖子吧,这里有点回贴不对主题了。




9
 楼主| 发表于 2013-8-21 14:33:42 | 显示全部楼层
chenwu0815 发表于 2013-8-21 13:23
我想的是,从权限管理、动态实例化窗体,到窗体传值这一系列弄个完整方案。。
目前结合你的“动态实例化 ...

我不是给你回复了吗?
[code=csharp]/// <summary>  
        /// 打开新的子窗体  
        /// </summary>  
        /// <param name="strName">窗体的类名</param>  
        /// <param name="AssemblyName">窗体所在类库的名称</param>   
        public static void CreateForm(string strName, string AssemblyName)
        {
            string path = AssemblyName;//项目的Assembly选项名称  
            string name = strName; //类的名字  
            Form doc = (Form)Assembly.Load(path).CreateInstance(name);
            doc.Show();
        }[/code]
你看这个代码里的 Form doc = (Form)Assembly.Load(path).CreateInstance(name);
这个doc就是你实例化后的窗体对象,
如果你事先在窗体里有定义的Public的方法就可以这样用
doc.SetAtr(naem,sex,age);
SetAtr事先写到你实例化的窗体里。
这样不就传值了吗?
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2025-12-15 06:57

© 2014-2021

快速回复 返回顶部 返回列表