VS2003自带的菜单说实在的。。。土,太土了,掉渣的土啊~~(-_-b),VS2005里的漂亮,可是公司用的03(哭一个),没办法,发扬懒人精神,找现成的(^_^)嘿嘿。。。。
说干就干,在网上查了一下,有很多实现带图标菜单的例子和源代码,大概看了几个,都不是很满意,虽然都实现了图标,SideBar的功能,可是却没有找到一个解决(&)助记符的问题,都是直接将(&)显示出来,不做处理(也可能是我笨,没有找到,呵呵~希望高人们不要扔我鸡蛋哦~),没有办法,只好自己参考各位高人的代码,写了一个VS2003风格的MenuItem,在这里先要谢谢这些高人了(^_^),如果哪位高人在下边的源码里发现自己代码的痕迹的话,希望不要告我哦~
好了,转入正题~
先来看一下最终效果~
VS2003自带的菜单说实在的。。。土,太土了,掉渣的土啊~~(-_-b),VS2005里的漂亮,可是公司用的03(哭一个),没办法,发扬懒人精神,找现成的(^_^)嘿嘿。。。。
说干就干,在网上查了一下,有很多实现带图标菜单的例子和源代码,大概看了几个,都不是很满意,虽然都实现了图标,SideBar的功能,可是却没有找到一个解决(&)助记符的问题,都是直接将(&)显示出来,不做处理(也可能是我笨,没有找到,呵呵~希望高人们不要扔我鸡蛋哦~),没有办法,只好自己参考各位高人的代码,写了一个VS2003风格的MenuItem,在这里先要谢谢这些高人了(^_^),如果哪位高人在下边的源码里发现自己代码的痕迹的话,希望不要告我哦~
好了,转入正题~
先来看一下最终效果~
目前这个MenuItem并不是很完美,还不能显示单选和复选状态(因为公司的程序里没有用到,所以偷了一个小懒,见量见量~^_^),以后有机会的话再补上吧~
说明见代码里的注释,帖出完整代码(^_^):
================================================================
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace Snowfox.Common.ComCtl
{
/**//// <summary>
/// 实现Visual Studio 2003风格菜单
/// </summary>
public class zxMenuItem : MenuItem
{
/**//// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
/**//// <summary>
/// 菜单项显示的图像
/// </summary>
public Image ItemIcon = null;
私有字段#region 私有字段
private string MenuText;
/**//// <summary>
/// 菜单项默认字体
/// </summary>
private Font TextFont = new Font("宋体",9);
/**//// <summary>
/// 快捷键助记符字体
/// </summary>
private Font MnemonicFont = new Font("宋体",9,FontStyle.Underline);
/**//// <summary>
/// 菜单项背景色
/// </summary>
private Brush BackColor = new Pen(Color.FromArgb(252,252,249)).Brush;
/**//// <summary>
/// 菜单项字体颜色
/// </summary>
private Brush TextColor = Brushes.Black;
/**//// <summary>
/// 分隔符及不可用菜单项颜色
/// </summary>
private Brush DisableColor = new Pen(Color.FromArgb(197,194,184)).Brush;
/**//// <summary>
/// 图标
/// </summary>
private Brush IconBackColor = new Pen(Color.FromArgb(239,237,222)).Brush;
/**//// <summary>
/// 选中项填充颜色
/// </summary>
private Brush SelectedColor = new Pen(Color.FromArgb(193,210,238)).Brush;
/**//// <summary>
/// 选中项边框颜色
/// </summary>
private Pen SelectedBorder = new Pen(Color.FromArgb(49,106,197));
/**//// <summary>
/// 分离快捷键助记符用字段
/// </summary>
private int TLen1,TLen2,TLen3;
private string TStr1,TStr2,TStr3;
#endregion
构造函数#region 构造函数
public zxMenuItem()
{
InitializeComponent();
this.OwnerDraw = true;
}
public zxMenuItem(string text) : base(text)
{
InitializeComponent();
this.OwnerDraw = true;
}
#endregion
/**//// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
组件设计器生成的代码#region 组件设计器生成的代码
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
重写方法#region 重写方法
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem (e);
try
{
MenuText = base.Text;
SizeF SizeMenu;
if ( MenuText == "-" )
{
e.ItemHeight = 5;
return;
}
if ( CheckIsTop() ) //如果为顶级菜单项
{
SizeMenu = e.Graphics.MeasureString( MenuText, TextFont );
e.ItemWidth = Convert.ToInt32(SizeMenu.Width) + 6;
}
else //如果为子菜单项
{
string sShortcut = GetShortCut();
if ( sShortcut.Trim() == "" )
{
SizeMenu = e.Graphics.MeasureString(MenuText,TextFont);
}
else
{
SizeMenu = e.Graphics.MeasureString(MenuText.PadRight(4,' ') + sShortcut,TextFont);
}
e.ItemWidth = Convert.ToInt32(SizeMenu.Width) + 36;
}
e.ItemHeight = Convert.ToInt32(SizeMenu.Height) + 6;
//如果有助记符则分离
if ( MenuText.IndexOf("&") != -1 )
{
TStr1 = MenuText.Substring(0,MenuText.IndexOf("&"));
TStr2 = MenuText.Substring(MenuText.IndexOf("&") + 1,1);
TStr3 = MenuText.Substring(MenuText.IndexOf("&") + 2);
TLen1 = Convert.ToInt32(e.Graphics.MeasureString(TStr1,TextFont).Width) - 3;
//TLen2 = Convert.ToInt32(e.Graphics.MeasureString(TStr2,MnemonicFont).Width);
//TLen2 = ( Char.IsUpper(TStr2,0) ? 10 : 7 );
TLen2 = 7;
TLen3 = Convert.ToInt32(e.Graphics.MeasureString(TStr3,TextFont).Width);
if ( TLen1 < 0 )
{
TLen1 = 0;
}
}
}
catch ( Exception )
{
e.ItemHeight = 20;
e.ItemWidth = 80;
}
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
Rectangle mRect = e.Bounds;
Graphics g = e.Graphics;
//Rectangle SideBarRect = new Rectangle(mRect.X,mRect.Y,25,mRect.Height);//图标背景区域
Rectangle TextRect = new Rectangle(mRect.X + 1,mRect.Y + 3,mRect.Width - 2,mRect.Height - 6);//顶级项文本区
Rectangle SubTextRect = new Rectangle(mRect.X + 30,mRect.Y + 5,mRect.Width - 45,mRect.Height - 10);//子项文本区
StringFormat strFormat = new StringFormat();
Brush bTmp = null;
Pen pTmp = null;
if ( CheckIsTop() && MenuText != "-" )//如果为顶级菜单项
{
//rTmp用来调整顶级菜单项选中时的样式,防止当顶级项无子项时下边出现残留边框或有子项时顶级项与菜单间出现边框。
Rectangle rTmp = new Rectangle(mRect.X,mRect.Y,mRect.Width - 1,mRect.Height - 1);
bTmp = System.Drawing.SystemBrushes.Control;//默认正常状态
if ( this.Enabled ) //如果可用判断高亮及选择状态,否则不处理,使用正常背景。
{
if ( ( e.State & DrawItemState.HotLight ) == DrawItemState.HotLight )//高亮状态
{
bTmp = SelectedColor;
pTmp = SelectedBorder;
}
else if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected )//选择状态
{
bTmp = IconBackColor;
pTmp = SelectedBorder;
if ( this.MenuItems.Count > 0 )
{
rTmp = new Rectangle(mRect.X,mRect.Y,mRect.Width - 1,mRect.Height);
}
}
}
g.FillRectangle(bTmp,mRect);//填充颜色
if ( pTmp != null )//如果非标准状态,则画边框线
{
g.DrawRectangle(pTmp,rTmp);
}
if ( this.Enabled )//如果可用
{
bTmp = TextColor;
}
else//不可用
{
bTmp = DisableColor;
}
if ( MenuText.IndexOf("&") == -1 )//如果无助记符
{
strFormat.Alignment = StringAlignment.Center;
g.DrawString(MenuText,TextFont,bTmp,TextRect,strFormat);
}
else//如果有助记符
{
g.DrawString(TStr1,TextFont,bTmp,TextRect.X + ((TextRect.Width - TLen1 - TLen2 - TLen3)/2),TextRect.Y);
g.DrawString(TStr2,MnemonicFont,bTmp,TextRect.X + ((TextRect.Width - TLen1 - TLen2 - TLen3)/2) + TLen1,TextRect.Y);
g.DrawString(TStr3,TextFont,bTmp,TextRect.X + ((TextRect.Width - TLen1 - TLen2 - TLen3)/2) + TLen1 + TLen2,TextRect.Y);
}
}
else//子菜单项
{
g.FillRectangle(BackColor,mRect);//画背景色
g.FillRectangle(IconBackColor,mRect.X,mRect.Y,25,mRect.Height);//画图标背景(即SideBar区域)
if ( MenuText == "-" )//如果此项为分隔符
{
//Brush bLine = new Pen(Color.FromArgb(197,194,184)).Brush;
g.FillRectangle(DisableColor,mRect.X + 31,mRect.Y + 2,mRect.Width - 31,mRect.Height - 4);
}
else//正常菜单项
{
Rectangle IconRect = new Rectangle(mRect.X + 4,mRect.Y + 2,16,16);//画图标的位置
if ( this.Enabled )//如果可用
{
bTmp = TextColor;
if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected ) //如果子菜单处于选中状态
{
g.FillRectangle(SelectedColor,mRect);
g.DrawRectangle(SelectedBorder,mRect.X,mRect.Y,mRect.Width - 1,mRect.Height - 1);
//改变图标位置
IconRect.Y -= 1;
IconRect.X -= 1;
}
}
else//不可用
{
bTmp = DisableColor;
}
if ( ItemIcon != null )//如果图标不为空,画图标
{
g.DrawImage(ItemIcon,IconRect);
}
if ( MenuText.IndexOf("&") == -1 )//如果无助记符
{
strFormat.Alignment = StringAlignment.Near;
g.DrawString(MenuText,TextFont,bTmp,SubTextRect,strFormat);
}
else//有助记符
{
g.DrawString(TStr1,TextFont,bTmp,SubTextRect.X,SubTextRect.Y);
g.DrawString(TStr2,MnemonicFont,bTmp,SubTextRect.X + TLen1,SubTextRect.Y);
g.DrawString(TStr3,TextFont,bTmp,SubTextRect.X + TLen1 + TLen2,SubTextRect.Y);
}
//如果有快捷键,画
string sShortcut = GetShortCut();
if ( sShortcut.Trim() != "" )
{
strFormat.Alignment = StringAlignment.Far;
g.DrawString(sShortcut,TextFont,bTmp,SubTextRect,strFormat);
}
}//End IF (分隔符 OR 正常菜单)
}//End IF (顶级菜单 OR 子菜单)
}//End Method OnDrawItem()
#endregion
辅助方法#region 辅助方法
/**//// <summary>
/// 检查此菜单项是否为顶级菜单项
/// </summary>
/// <returns>如果为顶级菜单项返回true,否则返回false</returns>
private bool CheckIsTop()
{
if ( typeof(MainMenu) == this.Parent.GetType() )
{
return true;
}
else
{
return false;
}
}
/**//// <summary>
/// 取此菜单项快捷键
/// </summary>
/// <returns>如果有快捷键则返回快捷键字串,如果没有则返回空串</returns>
private string GetShortCut()
{
string sResult = "";
try
{
if ( this.ShowShortcut && (!this.IsParent) && (this.Shortcut != Shortcut.None) )
{
sResult = this.Shortcut.ToString();
sResult = sResult.Replace("Ctrl", "Ctrl+");
sResult = sResult.Replace("Alt", "Alt+");
sResult = sResult.Replace("Shift","Shift+");
}
}
catch ( Exception )
{
return "";
}
return sResult;
}
#endregion
}
}
====================================================================
转载请注明出处~谢谢~^_^