当前位置:首页>>ASP.NET教程>>Asp.NET综合技巧>>用c#绘制Office2003样式的菜单
用c#绘制Office2003样式的菜单
2009/11/8 13:19:18
我的方法是重写MenuItem类,在写的过程中发现用GDI+实际测量出来的文本的大小不是很准确,还有文本也不能很好对齐,固在代码里可以时常看到很多多加上去的数字.我想原理就不用我讲了吧,下面的代码注释的很

清楚了:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace officeMenu
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class officeMenuItem:MenuItem
{
public officeMenuItem(bool IsApplyofficeMenu,string ItemText)
{
if(IsApplyofficeMenu)
{
this.Text=ItemText;
this.OwnerDraw=true;
font=new Font("宋体",9f,GraphicsUnit.Point);
}
else
{
this.Text=ItemText;
this.OwnerDraw=false;
}
}

private Font font;
private StringFormat strFormat=new StringFormat();
private string ItemText="";
private string iconPath="";

//定义绘制的时候的各种笔刷
private LinearGradientBrush TopMenuHostLightBrush;
private SolidBrush TopMenuDefaultBrush;
private SolidBrush FontDefaultBrush;
private LinearGradientBrush TopMenuSelectedBrush;
private SolidBrush MenuDefaultBrush;
private SolidBrush MenuDefaultSelectedBrush;
private SolidBrush MenuCheckBrush;
private LinearGradientBrush MenuSideBarBrush;
private SolidBrush MenuDefaultGrayedBrush;
//定义绘制的时候所需的各种线条
private Pen TopMenuPen;
private Pen MenuDefaultPen;
//定义需要的矩形结构
private Rectangle SideBarRect;
private Rectangle CheckedRect;
private Rectangle TopMenuRect;
private Rectangle ShortcutRect;



//定义图标
public string IconPath
{
get
{
return iconPath;
}
set
{
iconPath=value;
}
}

//判断菜单是否是顶级菜单
private bool CheckIsTop()
{
if(typeof(MainMenu)==this.Parent.GetType())
{
return true;
}
else
{
return false;
}
}
//获取菜单的快捷键
private string GetShortCut()
{
string shortcut="";
try
{
if(this.ShowShortcut==true && (!this.IsParent) && (!(this.Shortcut==Shortcut.None)))
{
shortcut=this.Shortcut.ToString();
shortcut=shortcut.Replace("Ctrl","Ctrl+");
shortcut=shortcut.Replace("Alt","Alt+");
shortcut=shortcut.Replace("Shift","Shift+");
}
}
catch
{
return "";
}
return shortcut;
}
//重写测量函数
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem (e);

try
{
ItemText=this.Text;
SizeF SizeMenuText;
if(this.ItemText=="-") //设置分割线的高度
{
e.ItemHeight=5;
return;
}

string getedShortcut=this.GetShortCut();
if(!this.CheckIsTop()) //如果不是顶级菜单
{
SizeMenuText=e.Graphics.MeasureString(ItemText+"".PadRight(4,' ')+getedShortcut,this.font);
e.ItemWidth=Convert.ToInt32(SizeMenuText.Width)+26;
}
else
{
SizeMenuText=e.Graphics.MeasureString(ItemText,this.font);
e.ItemWidth=Convert.ToInt32(SizeMenuText.Width)-4;
}
if(this.Visible)
{
e.ItemHeight=Convert.ToInt32(SizeMenuText.Height)+6;
}
else
{
e.ItemHeight=0;
}

}
catch
{
e.ItemHeight=20;
e.ItemWidth=80;
}
}
//重写绘图函数
protected override void OnDrawItem(DrawItemEventArgs e)
{
if(this.Visible)
{
base.OnDrawItem (e);
Rectangle MenuRect=e.Bounds;
ItemText=this.Text;
Graphics g=e.Graphics;

//绘制边框时需要的特殊矩形
SideBarRect=new Rectangle(MenuRect.X,MenuRect.Y,25,MenuRect.Height);
//绘制选择框时需要的矩形
CheckedRect=new Rectangle(MenuRect.X+1,MenuRect.Y+1,24,MenuRect.Height-2);
//绘制顶菜单时需要的矩形
TopMenuRect=new Rectangle(MenuRect.X+1,MenuRect.Y+3,MenuRect.Width,MenuRect.Height);
//绘制shortcut用到的矩形
ShortcutRect=new Rectangle(MenuRect.X,MenuRect.Y+4,MenuRect.Width-10,MenuRect.Height);

//定义绘制的时候的各种笔刷
TopMenuHostLightBrush=new LinearGradientBrush(MenuRect,Color.White,Color.FromArgb(220,134,56),90f); //顶级菜单发生HOTLIGHT 时显示的颜色
TopMenuDefaultBrush=new SolidBrush(SystemColors.Control); //顶级菜单默认的颜色
FontDefaultBrush=new SolidBrush(Color.Black); //字体默认的颜色
TopMenuSelectedBrush=new LinearGradientBrush(MenuRect,Color.White,Color.FromArgb(95,109,126),90f); //顶级菜单选中时的颜色
MenuDefaultBrush=new SolidBrush(Color.White); //默认菜单的颜色
MenuDefaultSelectedBrush=new SolidBrush(Color.FromArgb(247,218,157)); //菜单选中时的颜色
MenuCheckBrush=new SolidBrush(Color.FromArgb(225,143,70)); //当菜单CHECKED属性为真的时显示的颜色
MenuSideBarBrush=new LinearGradientBrush(SideBarRect,Color.White,Color.FromArgb(149,160,174),0f);//绘制侧栏
MenuDefaultGrayedBrush=new SolidBrush(Color.FromArgb(105,105,105));//菜单不可用时
//定义绘制的时候所需的各种线条
TopMenuPen=new Pen(Brushes.Black,1f); //顶级菜单的边框
MenuDefaultPen=new Pen(new SolidBrush(Color.FromArgb(60,60,115)),1f); //正常选择时的边框

//开始绘制****************************************************
if(this.CheckIsTop() && this.ItemText!="-") //如果是顶级菜单
{
bool IsDraw=false;//定义一个变量保证正常显示的只绘制一次 避免浪费资源
strFormat.Alignment=StringAlignment.Center;
if(IsDraw==false) //绘制正常显示时的图像
{
g.FillRectangle(TopMenuDefaultBrush,MenuRect);
g.DrawString(ItemText,this.font,FontDefaultBrush,TopMenuRect,strFormat);
}

//绘制HOTLIGHT时的图像
if((e.State & DrawItemState.HotLight)==DrawItemState.HotLight) //突出显示时
{
g.FillRectangle(TopMenuHostLightBrush,MenuRect);
g.DrawRectangle(TopMenuPen,MenuRect.X,MenuRect.Y,MenuRect.Width-1,MenuRect.Height-1);
g.DrawString(ItemText,this.font,FontDefaultBrush,TopMenuRect,strFormat);
IsDraw=true;
}
//绘制菜单选中时的图像
if((e.State & DrawItemState.Selected)==DrawItemState.Selected)
{
g.FillRectangle(TopMenuSelectedBrush,MenuRect);
g.DrawRectangle(TopMenuPen,MenuRect.X,MenuRect.Y,MenuRect.Width-1,MenuRect.Height-1);
g.DrawString(ItemText,this.font,FontDefaultBrush,TopMenuRect,strFormat);
IsDraw=true;
}
}
else //非顶级菜单时
{
if(this.ItemText!="-")
{
bool IsDraw=false;
if(IsDraw==false) //正常显示时
{
g.FillRectangle(MenuDefaultBrush,MenuRect);
g.FillRectangle(MenuSideBarBrush,MenuRect.X,MenuRect.Y,25,MenuRect.Height);
g.DrawString(ItemText,this.font,FontDefaultBrush,MenuRect.X+26,MenuRect.Y+4);
//绘制shortcut
string shortcut=this.GetShortCut();
strFormat.Alignment=StringAlignment.Far;
g.DrawString(shortcut,this.font,FontDefaultBrush,ShortcutRect,