在netMarketing/winformHelper/dynMenu.cs 这个类是动态菜单的业务逻辑。
它的配置窗体位于另一个工程 UserUI/Dialog/dynMenuSteup.cs 中。
dynMenuSteup.cs 包含了netMarketing类的引用。
但是netMarketing类中又想弹出UserUI工程中的对话窗,但是你不可能再包含UserUI的引用,因为这样就是循环引用了。
VS会对这类引用直接警告并且阻止。
因此,勇哥决定利用反射直接取得模块UserUI中的窗体使用。
下面的代码即可实现目的:
Assembly assem = Assembly.LoadFile(Environment.CurrentDirectory + "\\UserUI.dll"); Type[] t1 = assem.GetTypes(); var f1 = (Form)assem.CreateInstance("UserUI.Dialog.dynMenuSteup", true, BindingFlags.Default, null, new object[] { this }, null, null); f1.ShowDialog();
Assembly.LoadFile() 它需要指定含模块名的全路径。如果模块不是dll而一个类,则需要指定类名。 CreateInstance()第一个参数需要指定程序集点路径表示的窗口类的名字。 通常你并不会知道这个程序集点路径是个什么样子,因为你只知道窗口类的名字。 可以用下面这个句代码查看: Type[] t1 = assem.GetTypes();
下图是查看的结果,箭头所指的就是我们调用窗口的程序集点路径名。
另外,如果你的窗体构造函数为空,则不需要在CreatInstace() 函数中传入那么多的参数。就一句:
var f1 = (Form)assem.CreateInstance("UserUI.Dialog.dynMenuSteup")就行了。 下面给出一个加了注释的完整函数调用:
/// <summary> /// 由程序集反射出Form并且显示出来 /// </summary> /// <param name="dllPathName">如果模块为dll则这里应该为含dll名的路径串。否则为类名</param> /// <param name="AssemblyName">窗体的程序集全路径名,例如"UserUI.Dialog.dynMenuSteup"</param> /// <param name="StructuralParameters">窗体的构造参数</param> /// <param name="isModeShow">是否为模态窗体显示方式</param> public static void CreateFormAndShow(string dllPathName, string AssemblyName, object StructuralParameters=null,bool isModeShow=true) { Assembly assem = Assembly.LoadFile(dllPathName); var f1=new Form(); if (StructuralParameters == null) f1 = (Form)assem.CreateInstance(AssemblyName); else f1 = (Form)assem.CreateInstance(AssemblyName, true, BindingFlags.Default, null, new object[] { StructuralParameters }, null, null); if (isModeShow) f1.ShowDialog(); else f1.Show(); }
这样只需要这样调用就可以了:
CreateFormAndShow(Environment.CurrentDirectory + "\\UserUI.dll", "UserUI.Dialog.dynMenuSteup",this);

