動態菜單 - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- 動態菜單 (http://www.webasp.net/article/9/8184.htm) |
| -- 作者:未知 -- 發佈日期: 2004-03-10 |
| 在不重新編譯主程序的情況下要對程序的功能進行擴充,我們可以使用動態生成菜單,將新增的窗體編譯成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讀取 } } |
| webasp.net |