winform动态生成窗体并实现传值返回

时间:2024-03-29 19:53:17

目前还在苦逼的折腾练手作,碰到了关于生成窗体和传值的需求
首先是生成窗体的需求:
首先,首页有众多按钮,都是用来指向各个功能窗口的,一个个是编写代码的话,太麻烦了;
其次,设计一个通用的筛选窗口,给不同的数据表界面进行查询筛选,在编写查询条件时,要给一些项目比较多的字段提供一个浏览查询功能,同样需要动态生成窗体……
这个需求倒是挺容易就找到了解决方案,直接贴出代码以供参考


		string strForm = (sender as Button).Tag.ToString();//我在设计界面里,已经将每个按钮的tag填好了需要创建的窗口类名
        object[] obj = new object[1] { sqlcon };//我传了个mysql连接字符串,显然,在调用的窗口类里,需要写一个相应的构造函数,这个就不必展示了吧
        Form form = GetInstance(strForm, obj) as Form;//调用下面的那个方法
        form.show();			
        //以上是我写在二十多个按钮共同的click事件方法里的创建窗口代码
        
        ///这个方法,或者说这里面的这句代码,是关键所在             
		public static object GetInstance(string instanceName, params object[] param)
        {
            return Assembly.Load(Assembly.GetAssembly(typeof(Index)).GetName().Name).CreateInstance(typeof(Index).Namespace + "." + instanceName, true, BindingFlags.CreateInstance, null, param, System.Threading.Thread.CurrentThread.CurrentCulture, null);
            //index,是我的主窗口类名。至于这句代码的功能,看VS的提示,虽然很长,但还是挺好懂的
        }

这段代码我改了改,就拿到了筛选窗口使用。
但接着新的问题就来了,怎么拿到用户选择的返回值?

以下分隔线内是个我没解决的问题,可以当作是废话跳过
=====================
我曾经用过中间窗口方案,也就是添加个窗口(myForm),基本什么都没有,就是写入一个私有的string字段(result),再配上一个公开的获取方法(Result)。
然后让所有基本资料窗口继承这个中间窗口,这样,当用户选择完成后,就用 窗口.Result 拿到返回值。
不幸的是,不知是winform有毒,还是VS有毒(其实我更想说BUG),这个方法经常会这样:
winform动态生成窗体并实现传值返回
wuliao就是我做的其中一个基础资料窗口,继承中间窗口Form1后,设计器就会出错误,折腾多次,依旧没能搞明白其中的问题所在——曾经用简单的重启,就不再提示了,但同样的方法用第二次就无效了(微软,你的BUG是圣斗士级别的么),依旧报错
====================
嗯,废话结束,在确实需要传回值的情况下,考虑过使用委托,也就是将父窗口方法传给子窗口,不幸的是,在使用上述的动态新建窗口方法时,VS报错:方法组不能作为object 传递!
抱着试试也不会掉块肉的想法,我直接把当前窗口(this)作为参数,塞了进去,测试成功——在子窗口将当前窗口标题改写成功。
于是,就有了下面这个代码:

			父窗口的方法名略(参数略)
			{
				前略
				string strForm = “窗口名”;
                chuandi cd = new chuandi();//创建一个仅用来传递返回值的对象
                object[] obj = new object[2] { sqlcon ,cd };
                Form form = GetInstance(strForm, obj) as Form;
                if (form.ShowDialog() == DialogResult.OK)
                	dataGridView1.CurrentCell.Value = cd.zhi;
			}
			
			///仅用来传递返回值的对象类
			public class chuandi
		    {
		        public string zhi { get; set; }
		    }

			///某个基础资料窗口
			public partial class wuliao : Form
		    {
		    	private chuandi rcd;//声明对象,准备用来接收
		    	///构造函数
		        public wuliao(string sqlcon,chuandi cd)
		        {
		            InitializeComponent();
		            rcd = cd;
		        }
		        ///查询结束,确定返回值的方法
		        private void resultGet(string r)
		        {
		        	rcd.zhi = r;//返回值
		        	this.DialogResult = DialogResult.OK;
		        	this.close();
		        }
		    } 

目前看来,这个方案还没发现什么问题,如有大佬觉得不行,欢迎批评指点