我在做一个menubar ,menu 中的结构为这样的
  Menu 1
       Sub men 1
   Sub men 2
  Menu 2
       Sub men 1
   Sub men 2    我现在想将 Menu 中的所有菜单存放在一个 XML 中
         <?xml version="1.0" encoding="gb2312"?>
<root>
  <Main_Menu>
       <Main_Menu_Item Menu_Title="Menu 1"  PointObject="men1">
          <Item Menu_Title=" Sub men 1" PointObject=" Submen1" />
          <Item Menu_Title=" Sub men 2" PointObject=" Submen2" />
    </Main_Menu_Item>
  <Main_Menu_Item Menu_Title="Menu 2"  PointObject="men2">
                              <Item Menu_Title=" Sub men 1" PointObject=" Submen1" />
          <Item Menu_Title=" Sub men 2" PointObject=" Submen2" />
    </Main_Menu_Item>
  </Main_Menu>
</root> Menu_Title 为菜单所显示的标题, PointObject 为 对应 win form 的名称 eg : Submen1.cs  的PointObject 为 "Submen1" 现在的问题是: 当用户点击 "Menu 1" 下面的 "Sub men 1" 时如何根据 "Submen1"  这个名词来调用 Submen1.cs  同时在显示Submen1 winform时制 同一个用户只能打开一次

解决方案 »

  1.   

    看标题应该用反射~~但看楼主描述,似乎应该使用FindControl
      

  2.   

    这段是自动生成菜单,并为每个菜单项生成事件的代码,是在vs2005里面写的,vs2003也是大同小异,里面的菜单名加载是引用资源里的文件,换成xml文件就行了。
            public static void AddSkinMenu(ToolStripMenuItem toolMenu)
            {
                DataSet skin = new DataSet();
                try
                {
                    
                    skin.ReadXml("skin.xml",XmlReadMode.Auto);
                }
                catch
                {            }
                if (skin==null||skin.Tables.Count < 1)
                {
                    skin = new DataSet();
                    skin.Tables.Add("skin");
                    skin.Tables["skin"].Columns.Add("style");
                    System.Data.DataRow dr = skin.Tables["skin"].NewRow();
                    dr[0] = "系统默认";
                    skin.Tables[0].Rows.Add(dr);
                    skin.WriteXml("skin.xml", XmlWriteMode.IgnoreSchema);
                }
                foreach (SkinType st in (SkinType[])System.Enum.GetValues(typeof(SkinType)))
                {
                    toolMenu.DropDownItems.Add(new ToolStripMenuItem(st.ToString()));                toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
                    if (st.ToString() == skin.Tables[0].Rows[0][0].ToString())
                    {
                        ((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
                        frm_Main_Click(toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1], null);                }            }
                
                toolMenu.DropDownItems.Add(new ToolStripMenuItem("系统默认"));
                toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1].Click += new EventHandler(frm_Main_Click);
                if (skin.Tables[0].Rows[0][0].ToString() == "系统默认")
                {
                    ((ToolStripMenuItem)toolMenu.DropDownItems[toolMenu.DropDownItems.Count - 1]).Checked = true;
                }
                
               
                
            }
      

  3.   

    to:  Sharp Shooter
     findcontrol 是行不通的,因为查找的对象不是个 control 而是一个尚未实例化的 对象引用to: alldj(灵山妖姬) 
     你的方法是可行的但,不是我想要的,我现在关问题是 能否通对 Winform 的名称来实例化该对
    象望朋友帮忙
      

  4.   

    用反射做
    先把submen.cs编译成.dll放在bin里
    然后加载。
    Assembly a = Assembly.Load("namespace.submen1.dll");
    (Form)Activator.CreateInstance(a.GetTypes()).ShowDialog();
      

  5.   

    反射是可以,但是可能有些损耗性能其实这种问题如果有个统一的命名规则的话、
    直接findcontrol
    或者将control和xml title 弄一个dictionary 调用
    应该是个不错的解决方案毕竟这样没有反射损耗性能
      

  6.   

    如果你要调用的类直接就和主窗口在一个项目里的话,用
    Assembly a = Assembly.GetExecutingAssembly()就可以获得当前的Assembly
    然后Type t = a.GetType(类名)获得类(最好是带namespace的全名)
    最后Activator.CreateInstance(t)即可,谨慎起见最好这三句套个try作意外处理
      

  7.   

    private void button1_Click(object sender, EventArgs e)
            {
                string frm = "Form2";
                for (int i = 0; i < Application.OpenForms.Count; i++)
                {
                    if (Application.OpenForms[i].Name == frm)
                    {
                        return;
                    }
                }
                System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
                //object obj=thisDll.CreateInstance("Form2");
                Type typForm = ass.GetType( "testDLL."+frm );
                if( typForm == null ) return;
                Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;            if( frmTest == null ) return;
                else
                {
                    frmTest.Name=frm;
                    frmTest.Show();
                }        }
      

  8.   

    不行,我在Vs2003中不能用OpenForms的属性
      

  9.   


            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        [DllImport("user32.dll", EntryPoint = "FindWindowEx")] //找子窗体
            private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);        [DllImport("User32.dll", EntryPoint = "SendMessage")] //用于发送信息给窗体
            private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
            /// <summary>
            /// 查找是否已创建窗体
            /// </summary>
            /// <param name="FormTitle">标题名称</param>
            /// <returns></returns>
            public static bool SearchForm(string FormTitle)
            {
                IntPtr ParenthWnd = new IntPtr(0);
                IntPtr EdithWnd = new IntPtr(0);            //查到窗体,得到整个窗体 
                ParenthWnd = FindWindow(null,FormTitle);
                if (!ParenthWnd.Equals(IntPtr.Zero))
                {
                    return true;
                }
                else
                {
                    return false;
                }        }
    private void button1_Click(object sender, EventArgs e)
            {
                string frm = "FormTitle";
                if (SearchForm(frm))
    {
        return;
    }
    frm="Form2";
                System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
                //object obj=thisDll.CreateInstance("Form2");
                Type typForm = ass.GetType( "testDLL."+frm );
                if( typForm == null ) return;
                Form frmTest = typForm.InvokeMember( null,BindingFlags.DeclaredOnly |BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.CreateInstance,null,null,null ) as Form;            if( frmTest == null ) return;
                else
                {
                    frmTest.Name=frm;
                    frmTest.Show();
                }        }
      

  10.   

    to :alldj(灵山妖姬) 
    找不到BindingFlags
      

  11.   

    System.Reflection.BindingFlags 可以,测试中
      

  12.   

    可以了,谢谢大家to :alldj(灵山妖姬) 
    你的方法可行