赛迪网 >> 技术应用子站 >> ASP
动态菜单
作者: 来源:cfan 发布时间:2006.07.27
【Java专区】 【网络安全】 【网管专区】 【linux专区】 【数据库专区】 【进入论坛】 【IT博客】 
【Eclipse】  【PHP】  【DB2】  【Ajax】  【Struts】  【Spring】 

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



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



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



dymenu.xml内容如下





<主菜单>动态菜单1


<子菜单>OpenForm1


<菜单DLL>MyForms.dll


<菜单Func>OpenForm1


<子菜单>OpenForm2


<菜单DLL>MyForms.dll


<菜单Func>OpenForm2



<主菜单>动态菜单2


<子菜单>OpenForm3


<菜单DLL>MyForms.dll


<菜单Func>OpenForm3



<主菜单>动态菜单3


<子菜单>OpenForm4


<菜单DLL>MyForms.dll


<菜单Func>OpenForm4





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


{


///


/// Form1 的摘要说明。


///


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;


///


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


///


private System.ComponentModel.Container components = null;



public Form1()


{


//


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


//


InitializeComponent();



//


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


//


}



///


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


///


protected override void Dispose( bool disposing )


{


if( disposing )


{


if (components != null)


{


components.Dispose();


}


}


base.Dispose( disposing );


}



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


///


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


/// 此方法的内容。


///


private void InitializeComponent()


{


this.mainMenu1 = new System.Windows.Forms.MainMenu();


//


//动态生成菜单


//


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


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


for(int i=0;i
{


MenuItem newDyMainItem = new MenuItem(mMenus[i]);


this.mainMenu1.MenuItems.Add(newDyMainItem);


for(int j=0;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



///


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


///


[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读取


}


}







最全面的台式机导购资讯,形成全方位的台式机导购平台
评论】 【推荐】 【 】 【打印】 【关闭
*姓  名: 更多资料 了解方案 认识厂商
*单位名称:
*联系电话:
*电子邮件:
    
◆ 相关文章
· 从MP3中提取歌曲信息 2004-08-20
· net中交易处理的解决方案 2004-11-23
· 亿众国际点对点文件传输程序 2004-04-26
· 连接池的管理 2003-01-15
· 如何在调用线程的时候传递参数 2004-02-28