欢迎光临
我们一直在努力

动态菜单-.NET教程,安装和部署

建站超值云服务器,限时71元/月

在不重新编译主程序的情况下要对程序的功能进行扩充,我们可以使用动态生成菜单,将新增的窗体编译成dll文件,然后在主程序的菜单定义文件中注册,即可解决,以后程序升级,只需将对应的dll覆盖。

1.菜单定义文件可以使用ini或xml格式,这里使用的是xml格式

定义主菜单,子菜单,子菜单对应的dll,子菜单对应的函数

dymenu.xml内容如下

<?xml version=1.0?>

<root>

<主菜单>动态菜单1

<子菜单>openform1</子菜单>

<菜单dll>myforms.dll</菜单dll>

<菜单func>openform1</菜单func>

<子菜单>openform2</子菜单>

<菜单dll>myforms.dll</菜单dll>

<菜单func>openform2</菜单func>

</主菜单>

<主菜单>动态菜单2

<子菜单>openform3</子菜单>

<菜单dll>myforms.dll</菜单dll>

<菜单func>openform3</菜单func>

</主菜单>

<主菜单>动态菜单3

<子菜单>openform4</子菜单>

<菜单dll>myforms.dll</菜单dll>

<菜单func>openform4</菜单func>

</主菜单>

</root>

2.菜单对应的myforms.dll

myforms.cs 代码如下:

using system;

namespace myforms

{

public class myforms

{

public myforms()

{

}

public void openform1(system.windows.forms.form mainf)

{

form1 fm = new form1();

fm.mdiparent = mainf;

fm.show();

}

public void openform2(system.windows.forms.form mainf)

{

form2 fm = new form2();

fm.mdiparent = mainf;

fm.show();

}

public void openform3(system.windows.forms.form mainf)

{

form3 fm = new form3();

fm.mdiparent = mainf;

fm.show();

}

public void openform4(system.windows.forms.form mainf)

{

form4 fm = new form4();

fm.mdiparent = mainf;

fm.show();

}

}

}

另外还有4个窗体form1 form2 form3 form4

这里使用的namespace 构造函数 都和dll的名字一致,是为了方便后面主程序调用

3.主程序dymenu.cs

using system;

using system.drawing;

using system.collections;

using system.componentmodel;

using system.windows.forms;

using system.data;

using system.reflection;

using system.xml;

namespace dymenu

{

/// <summary>

/// form1 的摘要说明。

/// </summary>

public class form1 : system.windows.forms.form

{

private system.windows.forms.mainmenu mainmenu1;

//主菜单

private string[] mmenus;

//子菜单

private string[][] mitems;

//子菜单对应的dll

private string[][] mdlls;

//子菜单对应的函数

private string [][] mfuncs;

/// <summary>

/// 必需的设计器变量。

/// </summary>

private system.componentmodel.container components = null;

public form1()

{

//

// windows 窗体设计器支持所必需的

//

initializecomponent();

//

// todo: 在 initializecomponent 调用后添加任何构造函数代码

//

}

/// <summary>

/// 清理所有正在使用的资源。

/// </summary>

protected override void dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.dispose();

}

}

base.dispose( disposing );

}

#region windows 窗体设计器生成的代码

/// <summary>

/// 设计器支持所需的方法 – 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

private void initializecomponent()

{

this.mainmenu1 = new system.windows.forms.mainmenu();

//

//动态生成菜单

//

readxml(); //从菜单定义文件dymenu.xml中读取数据放入定义菜单的数组中

//从数组中取出菜单定义动态生成菜单

for(int i=0;i<mmenus.length;i++)

{

menuitem newdymainitem = new menuitem(mmenus[i]);

this.mainmenu1.menuitems.add(newdymainitem);

for(int j=0;j<mitems[i].length;j++)

{

menuitem newdyitem = new menuitem(mitems[i][j]);

newdymainitem.menuitems.add(newdyitem);

//将每个菜单的click事件指向同一个方法

newdyitem.click += new system.eventhandler(this.newclick);

}

}//end

//这里可以添加一些固定的菜单(不要定义index值,而且一定要在动态生成菜单的后面加,因为后面click事件判断是按index的值来确定的)

this.mainmenu1.menuitems.addrange(new system.windows.forms.menuitem[] {});

//

// form1

//

this.autoscalebasesize = new system.drawing.size(6, 14);

this.clientsize = new system.drawing.size(584, 341);

this.ismdicontainer = true;

this.menu = this.mainmenu1;

this.name = "form1";

this.text = "form1";

}

#endregion

/// <summary>

/// 应用程序的主入口点。

/// </summary>

[stathread]

static void main()

{

application.run(new form1());

}

//

//使用反射生成菜单事件

//

private void newclick(object sender, system.eventargs e)

{

menuitem item = (menuitem)sender;

menuitem par = (menuitem)item.parent;

int i = par.index;

int j = item.index;

string idll = mdlls[i][j];

string iclass = idll.substring(0,idll.indexof("."))

+ "."

+ idll.substring(0,idll.indexof("."));

string ifunc = mfuncs[i][j];

try

{

assembly asm = assembly.loadfrom(idll);

type mytype = asm.gettype(iclass);

methodinfo mi = mytype.getmethod(ifunc);

object obj = activator.createinstance(mytype);

mi.invoke(obj,new object[] {this});

}

catch(exception ex)

{

messagebox.show(ex.message);

}

}//end菜单事件

//

//读取菜单文件dymenu.xml

//

public void readxml()

{

xmldocument doc = new xmldocument();

try

{

doc.load("dymenu.xml");

}

catch(exception e)

{

messagebox.show(e.message);

}

xmlelement root = doc.documentelement;

xmlnodelist nodes = root.selectnodes("主菜单");

mmenus = new string[nodes.count];

mitems = new string[nodes.count][];

mdlls = new string[nodes.count][];

mfuncs = new string[nodes.count][];

int j=0;

foreach(xmlnode node in nodes)

{

mmenus[j] = node.innerxml.substring(0,node.innerxml.indexof("<")).trim();

xmlnodelist ns1 = node.selectnodes("子菜单");

int i=0;

mitems[j] = new string[ns1.count];

foreach(xmlnode n in ns1)

{

mitems[j][i] = n.innerxml.trim();

i++;

}

xmlnodelist ns2 = node.selectnodes("菜单dll");

i=0;

mdlls[j] = new string[ns2.count];

foreach(xmlnode n in ns2)

{

mdlls[j][i] = n.innerxml.trim();

i++;

}

xmlnodelist ns3 = node.selectnodes("菜单func");

i=0;

mfuncs[j] = new string[ns3.count];

foreach(xmlnode n in ns3)

{

mfuncs[j][i] = n.innerxml.trim();

i++;

}

j++;

}

}//end读取

}

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 动态菜单-.NET教程,安装和部署
分享到: 更多 (0)