正在阅读:.Net基础学习:动态菜单.Net基础学习:动态菜单

2004-02-14 09:34 出处:PConline 作者:lustful/CSDN 责任编辑:linjixiong

  在不重新编译主程序的情况下要对程序的功能进行扩充,我们可以使用动态生成菜单,将新增的窗体编译成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读取
   }
  }

关注我们

最新资讯离线随时看 聊天吐槽赢奖品