用C#实现office2003风格的菜单组件

来源:网络整理 责任编辑:栏目编辑 发表时间:2013-07-02 04:17 点击:

简介


仅仅使用一行简单的程序,你就能够使你的Windows窗体的所有菜单和上下文菜单具有office2003的菜单外观。同样地,你也可以只用一行程序,就能为你的菜单加上漂亮的图标。本文实现的是一个具有该功能的组件。如果你想让你的菜单恢复原来的外观,也只须调用End方法即可。

 

组件的使用


要正确使用组件,必须先将你的组件加入到工具箱中。然后将该组件从工具箱中拖放放到form窗体中。这时会看到你的form的设计页中多出了一个名为OfficeMenus1的图标,说明已经将菜单组件加入到了form中。紧接着调用如下方法:

//开始显示office 2003菜单OfficeMenus1.Start( FormName ); 注:FormName为要改变菜单风格的窗口名称。
同样,你也可以通过调用如下方法终止菜单的office2003风格,使之回到原始外观:
// 改变菜单的外观风格到原始状态OfficeMenus1.End();
为菜单顶添加图标也很简单,只须为工程添加一个ImageList(图像列表控件),然后将OfficeMenu组件的ImageList属性更改为你添加的ImageList,使用如下代码实现:
// 为菜单添加图像// OfficeMenus.AddPicture( MenuItem MenuItemToAddPictureTo, int ImageIndex );OfficeMenus1.ImageList = imageList1;OfficeMenus1.AddPicture(menuItem2, 1);

可以看出,只须如此几行代码就能轻松让你的菜单实现office2003风格。

组件的实现方法及原理


组件由三个类实现,这三个类分别为OfficeMenus,MainMenuItemDrawing和MenuItemDrawing,都位于命名空间Dev4Arabs中。由于实现代码较长,所以在此只给出了组件实现的思路。
组件实现的第一步是从System.ComponentModel.Component类派生类OfficeMenus。定义如下:
public class OfficeMenus : System.ComponentModel.Component
然后在类中定义两静态变量:

//图像列表用来存储菜单中用到的图标
static ImageList _imageList;
// 存储图片细节的一个名称集合,NameValueCollection的详细说明请查阅MSDN,该类主要用来使每个菜单的句柄与每个图标形成一一对应的关系,以便后面绘制菜单顶的图标时快速地找到某个菜单所对应的图标。
static NameValueCollection picDetails = new NameValueCollection();
接下来定义公共接口方法start和End。
公共接口方法Start的实现原理如下:
public void Start(Form form)

 先从Start传入的参数中获得该窗口的主菜单。接下来为每一个主菜单下的MenuItem添加MeasureItem事件 处理mainMenuItem_MeasureItem和DrawItem事件处理mainMenuItem_DrawItem, 将MenuItem的OwnerDraw属性设置为true,并使用InitMenuItem(Menu mi)方法对每个MenuItem应用改变。 然后再从form参数中获取该窗口的上下文菜单对象,对其调用InitMenuItem(Menu mi)应用改变。 最后循环查找窗口中包含的每个子控件的上下文菜单,对其应用改变。

 System.Windows.Forms.MainMenu menu = form.Menu;

 foreach ( MenuItem mi in menu.MenuItems )

 {

 mi.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(mainMenuItem_MeasureItem);

 mi.DrawItem += new System.Windows.Forms.DrawItemEventHandler(mainMenuItem_DrawItem);

 mi.OwnerDraw = true; InitMenuItem(mi);

 }

 ContextMenu cmenu = form.ContextMenu;

 if ( cmenu != null )

 {

InitMenuItem(cmenu);

foreach ( Control c in form.Controls )

{

  if ( c.ContextMenu != null )

   InitMenuItem(c.ContextMenu);

} catch

{

}

}

End方法与这类似,只须将InitMenuItem换为UninitMenuItem,这里就不再举出了。具体实现代码请下载附件!
为每个菜单应用改变的InitMenuItem方法的实现如下:
private void InitMenuItem(Menu mi)

{

循环查找mi中的每个MenuItem,为其添加MeasureItem事件处理menuItem_MeasureItem和DrawItem事件处理menuItem_DrawItem(注意,此处的事件处理方法名称与Start中对主菜单的事件处理方法名称不同),并将OwnerDraw属性设置为true。使用递归调用对每个查找到的MenuItem调用InitMenuItem方法,这样便可以对菜单项下的所有级别的子菜单项都应用到改变。

}
UninitMenuItem的定义与此类似。
menuItem_MeasureItem事件处理方法定义如下:
private void menuItem_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • 用C#制作屏幕捕获程序
    • .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上
    • 遍历ArrayList易犯错误
    • C#对XML操作:一个处理XML文件的类(1)
    • .NET简谈反射(动态调用)
    • 使用C#编写LED样式时钟控件
    • DataList嵌套问题 如何删除内层子DataList的记录
    • 怎样用C#实现完整文档打印功能
    • .NET简谈自定义事务资源管理器
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1