这是自己经常用到的一个动态菜单的基本原理
包含3个项目
主程序Client
接口IWindow
功能App1
需要引用:
using System.Reflection;
创建接口项目IWindow代码如下
namespace IWindow { public interface IWindow { string GetTitle();//用来获取窗口标题 object GetWindow(); //用来获取实例化的Form } }
菜单XML文件如下
<?xml version="1.0" encoding="utf-8" ?> <ROOT> <Menu> <Name>主菜单</Name> <NameSpace></NameSpace> <ModName></ModName> <SubMenu> <Menu> <Name>子菜单</Name> <NameSpace></NameSpace> <ModName></ModName> <SubMenu> <Menu> <Name>子菜单</Name> <NameSpace>App1</NameSpace> <ModName>Frm1</ModName> <SubMenu> </SubMenu> </Menu> </SubMenu> </Menu> <Menu> <Name>主菜单B</Name> <NameSpace></NameSpace> <ModName></ModName> <SubMenu> <Menu> <Name>子菜单</Name> <NameSpace></NameSpace> <ModName></ModName> <SubMenu> </SubMenu> </Menu> </SubMenu> </Menu> </ROOT>
创建一个类库项目,App1,引用IWindow项目
代码如下:
创建一个窗口Form1,代码略
在App1项目下建立一个类Frm(对应菜单XML中的ModName,实现IWindow接口
代码如下:
namespace App1 { public class Frm1 : IWindow.IWindow { string IWindow.IWindow.GetTitle() { return "这是一个标题";//这个标题会显示到Tabpage上 } object IWindow.IWindow.GetWindow() { return new Form1(); } } }
建立主程序项目,引用IWindow,在主界面上放置一个TabControl
动态加载菜单的代码略过
主程序加载窗口代码如下
private void LoadWindow(string Namespace, string AssemblyName, bool showCloseButton = true) { //参数中的showCloseButton没用,因为我在项目中使用的是DevExpress的TabControl Assembly ass = Assembly.Load(string.Format("{0}", Namespace));//对应XML文件中的NameSpace ,此处假设为App1 Type typ = ass.GetType(string.Format("{0}.{1}", Namespace, AssemblyName));//AssemblyName对应XML文件中的ModName ,此处假设为Frm1 IWindow.IWindow w = (IWindow.IWindow)Activator.CreateInstance(typ);//实例化反射对象 string tName = w.GetTitle();//获取窗口名称 Form f1 = (Form)w.GetWindow();//通过GetWindow方法来返回要显示的窗口对象 f1.Dock = DockStyle.Fill; f1.TopLevel = false; f1.FormBorderStyle = FormBorderStyle.None;//去掉窗口的边框 TabPage tb1 = new TabPage(); tb1.Controls.Add(f1); tb1.Text = tName; tabControl1.TabPages.Add(tb1); tabControl1.SelectedTab = tb1; f1.Show();//显示窗口 }
还没有评论,来说两句吧...