很多Windows 应用程序中的控件可以手工绘制,来达到更加生动的效果,可以使用窗体组件的ownerdraw属性来达到这个目的。Menu就是一个这样的组件,它允许我们手工绘制其界面。 这篇文章的主要目的在于向你解释如何用特定的字体,图片,背景颜色以及其他的图形对象来绘制自己定制的菜单。 第一步:创建一个简单的Windows Form应用程序 在默认的窗体上,添加一个“MainMenu”控件, 创建如下形式的菜单
在这里我们需要手工绘制的菜单不仅仅是顶级菜单,而且包括子菜单 对每个菜单项而言,手工绘制将调用如下两个函数.. DrawItem . 这个函数里将加入实际的绘图逻辑. object sender, System.Windows.Forms.DrawItemEventArgs e) object sender, System.Windows.Forms.MeasureItemEventArgs e) 现在我们需要为子菜单添加DrawItem 和 MeasureItem 事件处理函数. 对所有子菜单,我们创建不同的事件函数 object sender, System.Windows.Forms.MeasureItemEventArgs e) object sender, System.Windows.Forms.DrawItemEventArgs e) 注意:这里我们并不是对每个菜单项都创建一个相应的事件处理函数,尽管你可以这样做。相反的,我们通过一个通用的事件处理函数(mi_TopMenuItem_DrawItem)来处理所有顶级菜单项(File/Options/Help)的DrawItem事件,一个通用的事件处理函数来处理所有顶级菜单项的MeasureItem事件;一个通用的事件处理函数(mi_SubMenuItem_DrawItem)来处理所有的子菜单项(Open/Close…About)的DrawItem事件,一个通用的事件处理函数(mi_SubMenuItem_MeasureItem)来处理所有的子菜单的MeasureItem事件。 下面是顶级菜单的事件处理函数 private void mi_TopMenuItem_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { Brush sysBgBrush = new SolidBrush(SystemColors.Control); Brush focuseBgBrush = new SolidBrush(Color.CornflowerBlue); Font normalFont = new Font("Ariel", 10); Brush normalTxBrush = new SolidBrush(Color.Black); Pen bdrPen1 = new Pen(normalTxBrush, 2); Pen bdrPen2 = new Pen(normalTxBrush); Rectangle rc = new Rectangle(e.Bounds.X+1 , e.Bounds.Y+1, e.Bounds.Width-5, e.Bounds.Height-1); e.Graphics.FillRectangle(sysBgBrush , rc); MenuItem mOrigin = (MenuItem)sender ; string mItemText = mOrigin.Text ; StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center ; e.Graphics.DrawString(mItemText , normalFont, normalTxBrush , rc , sf ); //Console.WriteLine(e.State.ToString()); if ( e.State == (DrawItemState.NoAccelerator | DrawItemState.Selected) || e.State == ( DrawItemState.NoAccelerator | DrawItemState.HotLight) ) { e.Graphics.FillRectangle( focuseBgBrush, rc); e.Graphics.DrawString( mItemText , normalFont ,normalTxBrush, rc ,sf); e.Graphics.DrawRectangle(bdrPen2, rc ); } e.DrawFocusRectangle(); e.Graphics.DrawRectangle(bdrPen1, rc ); } private void mi_TopMenuItem_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) { e.ItemHeight = 25; e.ItemWidth = 75; } private void mi_SubMenuItem_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { Rectangle rc = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height); Brush sysBgBrush = new SolidBrush(SystemColors.Control); Brush focuseBrush = new SolidBrush(Color.CornflowerBlue); Font normalFont = new Font("Veranda", 10); Brush normalTxBrush = new SolidBrush(Color.Blue); Font focuseFont = new Font("Veranda", 10, FontStyle.Bold|FontStyle.Underline); Brush focuseTxBrush = new SolidBrush(Color.Yellow); Pen sysBdPen = new Pen(sysBgBrush); Pen focuseBdPen = new Pen(new SolidBrush(Color.Black)); //erase the previous track e.Graphics.FillRectangle(sysBgBrush , rc); MenuItem mOrigin = (MenuItem)sender ; string mItemText = mOrigin.Text ; StringFormat textFormat = new StringFormat(); textFormat.Alignment = StringAlignment.Far ; textFormat.LineAlignment = StringAlignment.Center; Rectangle rcText = rc ; rcText.Width-=5 ; e.Graphics.DrawString(mItemText , normalFont, normalTxBrush, rcText, textFormat ); e.Graphics.DrawRectangle(sysBdPen, rc ); if ( e.State == ( DrawItemState.NoAccelerator | DrawItemState.Selected)) { e.Graphics.FillRectangle(focuseBrush , rc); e.Graphics.DrawString( mItemText , focuseFont , focuseTxBrush, rcText,textFormat); e.Graphics.DrawRectangle(focuseBdPen, rc ); e.DrawFocusRectangle(); } Image useImage = null ; if ( mOrigin == mi_File_New ) { useImage = this.imageList1.Images[0]; } if ( mOrigin == mi_File_Open ) { useImage = this.imageList1.Images[1]; } if ( mOrigin == mi_File_Save ) { useImage = this.imageList1.Images[2]; } if ( useImage != null ) { SizeF sz = useImage.PhysicalDimension; e.Graphics.DrawImage(useImage, e.Bounds.X+5, ( e.Bounds.Bottom + e.Bounds.Top ) /2 - sz.Height/2); } } private void mi_SubMenuItem_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) { e.ItemHeight = 25; e.ItemWidth = 75; } 编译并执行. About the Author Shripad Kulkarni
点击文件 - > 新建 -> 项目 - > 创建一个新的C#WindowsForm应用程序:OwnerDrawMenu
对每个菜单项,设置其OwnerDraw属性为“True”
Measure Item . 这个函数被调用于设置菜单项的高度和宽度值.
在菜单项的事件列表里,我们将为其添加这两个事件函数.
选择“File”菜单的属性页.
点击“Event”标签页.
双击“DrawItem”选项.这将为“File”菜单添加一个默认的绘制事件处理函数.
private void mi_TopMenuItem_DrawItem(
双击“MeasureItem”选项。这将为“File”菜单添加一个默认的测量事件处理函数
private void mi_TopMenuItem_MeasureItem(
选中“Open”子菜单,同样的添加两个事件处理函数
private void mi_SubMenuItem_MeasureItem(
private void mi_SubMenuItem_DrawItem(
下面是详细步骤..
对其他的两个顶级菜单项“Options”、“Help”,在窗体设计器中选中它,选其属性页,选到事件页.
点击DrawItem 事件右边的下拉列表,选中mi_TopMenuItem_DrawItem.
点击MeasureItem 事件右边的下拉列表,选中mi_TopMenuItem_ MeasureItem.
对于每个子菜单,例如“Close / Exit / Security / Network / About”,选其属性页,选到事件页.
点击DrawItem 事件右边的下拉列表,选中mi_SubMenuItem_DrawItem.
点击MeasureItem 事件右边的下拉列表,选中mi_SubMenuItem_ MeasureItem.
现在对于每个菜单项我们都为其添加了DrawItem 和 MeasureItem的事件处理函数.
下面是子菜单的事件处理函数
本文地址:http://com.8s8s.com/it/it45320.htm