C# 求助插件dll内的窗体按键事件,如何调用主程序内的打开窗体方法

时间:2022-09-03 00:01:08
一、背景:程序根目录下有两个DLL文件(假设 AB两个DLL),每个DLL内都有一个窗体,程序可通过反射动态加载这两个DLL到自身tabControl.TabPages内。
二、需求:加载到tabControl.TabPages内的DLL窗体(假设为 A)中有一个按键。触发按键点击事件后如何调用另一个DLL窗体(假设为 B)展现到程序内的新的tabControl.TabPages内。还请各路大神指点,谢谢!

如下是窗体加载到主程序的代码
   if (childForm == null)
            {  
                childForm = (Form)Activator.CreateInstance(formType);
                 childForm.MdiParent = this;
                childForm.Name = "ChildForm" ;
                childForm.Text = childForm.Name;
                childForm.TopLevel = false;
                childForm.FormBorderStyle = FormBorderStyle.None;
                TabPage tab = new TabPage();
                tab.Text = bodename;
                tab.Controls.Add(childForm);
                tabControl.TabPages.Add(tab);
                tabControl.SelectedTab = tab; 
                childForm.Show();              
            }
            else
            {
                childForm.Show();
                childForm.BringToFront();
                childForm.Activate();
            }

4 个解决方案

#1


1.虽然Form能寄到TabPage上,但不建议这样实现,加个UserControl也许是个更好的选择
2.如果A Form的Button,知道具体的Button名称,通过反射可以拿到Button对象,然后注册Button对象的Click事件(不建议)
3.如果A Form有一个方法可以传入一个EventHandler类型的委托,那么可以在这个方法里注册Button的Click事件.
  通过反射,可以拿到实例对象的方法,再通过Invoke执行方法

  
              Form formA = new Form();
            //假如确实有Public的Register方法
            formA.GetType().GetMethod("Register").Invoke(formA, new object[] { new EventHandler((s, e) => MessageBox.Show("Hello world!"))});

#2


谢谢  bloodish的回复。
1、关于Form能寄到TabPage上的问题,谢谢提供新的方法。我会参考并进行验证的。很少有用到UserControl,因为很多方法无法使用呢。
2、FromA与FromB 都处于被调用的状态,互补不认识。如都加载到程序内,FromA怎么引用FromB呢?  怎么NEW出来呢?是不是在FormA里面再反射一次拿去FormB的方法? 之前我有测试过类似的方法,反射出来的窗口关闭再打开会报异常,可能没有释放或回收掉。
3、实现委托Invoke执行方法后,如何才能将次FormB寄到TabPage上呢?

如有简单的实例那就更好了,烦请大神相助,谢谢!

#3


楼主可以先了解一下IoC(控制反转)和DI(依赖注入)的基础知识,肯定会对你完成这个项目有帮助,拓宽思路.
1. FormA,FormB可以经过接口抽象,两者不需要相互引用
2. 主程序拥有FormA,FormB的实例, FormA对FormB的操作可以通过委托/事件转交给主程序执行,反之亦然
3. FormA,FormB都可以用单例实现,不做真正的close,就不存在释放的问题


#4


虽然暂时没有实现我的需求,但是还是谢谢了

#1


1.虽然Form能寄到TabPage上,但不建议这样实现,加个UserControl也许是个更好的选择
2.如果A Form的Button,知道具体的Button名称,通过反射可以拿到Button对象,然后注册Button对象的Click事件(不建议)
3.如果A Form有一个方法可以传入一个EventHandler类型的委托,那么可以在这个方法里注册Button的Click事件.
  通过反射,可以拿到实例对象的方法,再通过Invoke执行方法

  
              Form formA = new Form();
            //假如确实有Public的Register方法
            formA.GetType().GetMethod("Register").Invoke(formA, new object[] { new EventHandler((s, e) => MessageBox.Show("Hello world!"))});

#2


谢谢  bloodish的回复。
1、关于Form能寄到TabPage上的问题,谢谢提供新的方法。我会参考并进行验证的。很少有用到UserControl,因为很多方法无法使用呢。
2、FromA与FromB 都处于被调用的状态,互补不认识。如都加载到程序内,FromA怎么引用FromB呢?  怎么NEW出来呢?是不是在FormA里面再反射一次拿去FormB的方法? 之前我有测试过类似的方法,反射出来的窗口关闭再打开会报异常,可能没有释放或回收掉。
3、实现委托Invoke执行方法后,如何才能将次FormB寄到TabPage上呢?

如有简单的实例那就更好了,烦请大神相助,谢谢!

#3


楼主可以先了解一下IoC(控制反转)和DI(依赖注入)的基础知识,肯定会对你完成这个项目有帮助,拓宽思路.
1. FormA,FormB可以经过接口抽象,两者不需要相互引用
2. 主程序拥有FormA,FormB的实例, FormA对FormB的操作可以通过委托/事件转交给主程序执行,反之亦然
3. FormA,FormB都可以用单例实现,不做真正的close,就不存在释放的问题


#4


虽然暂时没有实现我的需求,但是还是谢谢了