五.绘制个性化菜单
先执行以下操作步骤下列步骤是通过菜单编辑器设计一个简单的菜单为后面重新绘制做基础
启动Visual Studio Net
选择菜单【文件】|【新建】|【项目】后弹出【新建项目】对话框
将【项目类型】设置为【Visual Basic项目】
将【模板】设置为【Windows应用程序】
在【名称】文本框中输入【自己画菜单】
在【位置】的文本框中输入【E:\VSNET项目】然后单击【确定】按钮这样在E:\VSNET项目目录中就产生了名称为自己画菜单的文件夹并在里面创建了名称为自己画菜单的项目文件
把Visual Studio Net的当前窗口切换到【Formvb(设计)】窗口并从【工具箱】中的【Windows窗体组件】选项卡中往Form窗体中拖入下列组件
一个MainMenu组件名称为MainMenu
选中MainMenu组件单击鼠标右键在弹出的菜单中选择编辑菜单并按照图所示界面设计菜单
图【自己画菜单】项目设计界面之一
此时保存上述步骤并单击快捷键F则得到图所示界面
图【自己画菜单】运行界面之一
这样通过菜单编辑器就完成了一个非常普通的菜单下面就对此菜单进行改造在改造之前要先设定项目中的三个MenuItem类实例的OwnerDraw属性值为True因为只有此属性值为True才会触发绘制菜单时所需要的DrawItem事件和MeasureItem事件之后再在上面项目的基础上执行下一步操作
把Visual Stuido Net的当前窗口切换到Formvb的代码编辑窗口并在InitializeComponent过程之后添加下列代码下列代码是绘制文件菜单项其作用是改变文件菜单项的字体大小和菜单项的其具体的绘制方法请参考下列代码中的注释
Private Sub MenuItem_DrawItem ( ByVal sender As Object ByVal e As SystemWindowsFormsDrawItemEventArgs ) Handles MenuItemDrawItem
Dim rfBound As RectangleF = New RectangleF ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根据DrawItemEventArgs参数获得菜单项矩形区域并存储到RectangleF类型实例中
Dim rfBound As Rectangle = New Rectangle ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根据DrawItemEventArgs参数获得菜单项矩形区域并存储到Rectangle类型实例中
Rectangle类型实例和RectangleF类型实例差不多但在后面代码中绘制菜单的函数是有区别的
eGraphicsFillRectangle(New SolidBrush(ColorLightGreen) rfBound)
以LightGreen色彩填充MenuItem菜单项对应的矩形区域
Dim s As MenuItem = CType ( sender MenuItem )
Dim s As String = sText
获得MenuItem菜单项的名称
Dim sfTemp As StringFormat = New StringFormat ( )
sfTempAlignment = StringAlignmentCenter
设定要画的菜单名称的对齐方式中间对齐
eGraphicsDrawString ( s New Font ( 宋体 FontStyleBold ) New SolidBrush ( ColorBlack ) rfBound sfTemp )
以中间对齐方式指定字体大小在指定的矩形区域重画菜单
If eState = ( DrawItemStateNoAccelerator Or DrawItemStateSelected ) Then
根据菜单项的当前绘制状态来绘制菜单项
eGraphicsFillRectangle ( New SolidBrush ( ColorLightYellow ) rfBound )
对菜单项所在的矩形区域进行色彩填充
eGraphicsDrawString ( s New Font ( 宋体 FontStyleBold ) New SolidBrush ( ColorBlack ) rfBound sfTemp )
对菜单项名称绘制
End If
eDrawFocusRectangle ( )
在 DrawItemEventArgs参数得到矩形范围内绘制聚焦框
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorBlack ) ) rfBound )
对菜单项的矩形区域绘制矩形框
End Sub
操作完成后保存修改此时再单击快捷键F运行程序可得到如图所示的界面
图【自己画菜单】运行界面之二
可见绘制的文件菜单项并没有完全显示出来并且后面的菜单项也没有显示这是因为菜单项的显示区域并没有设定而缺省的空间又不能完全显示造成的设定菜单项的显示区域大小是通过MeasureItem事件来完成的具体操作是在MenuItem的DrawItem事件后添加下列代码下列代码是是定义MenuItem的MeasureItem事件在此事件中设定菜单项的宽度(当然也可以设定高度等)
Private Sub MenuItem_MeasureItem ( ByVal sender As Object ByVal e As SystemWindowsFormsMeasureItemEventArgs ) Handles MenuItemMeasureItem
eItemWidth =
设定菜单项的宽度
End Sub
保存上述修改后单击快捷键F运行程序可得到图所示界面
图【自己画菜单】运行界面之三
可见文件菜单项就算绘制出来了由于其他菜单项没有绘制处理所以也未显示其他菜单项的绘制方法和文件菜单项的绘制方法基本相似以下是在上述完成的基础上对其他菜单项进行绘制从而得到图所示菜单的具体实现步骤
图【自己画菜单】运行界面之四
在Formvb中的MenuItem的MeasureItem事件处理程序之后添加下列代码下列代码是定义MenuItem的DrawItem事件其功能是对新建菜单项重新绘制
Private Sub MenuItem
_DrawItem ( ByVal sender As Object
ByVal e As System
Windows
Forms
DrawItemEventArgs ) Handles MenuItem
DrawItem
Dim rfBound As RectangleF = New RectangleF ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根据DrawItemEventArgs参数获得菜单项矩形区域并存储到RectangleF类型实例中
Dim rfBound As Rectangle = New Rectangle ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根据DrawItemEventArgs参数获得菜单项矩形区域并存储到Rectangle类型实例中
Rectangle类型实例和RectangleF类型实例差不多但在后面代码中绘制菜单的函数是有区别的
eGraphicsFillRectangle ( New SolidBrush ( ColorLightGray ) rfBound )
Dim s As MenuItem = CType ( sender MenuItem )
Dim s As String = sText
获得菜单项对应的文本名称
Dim sfTemp As StringFormat = New StringFormat ( )
sfTempAlignment = StringAlignmentCenter
设定文本在矩形区域的对齐方式
sfTempLineAlignment = StringAlignmentCenter
Dim rcText As RectangleF = rfBound
rcTextWidth =
eGraphicsDrawString ( s New Font ( 宋体 ) New SolidBrush ( ColorBlue ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorLightGray ) ) rfBound )
If eState = ( DrawItemStateNoAccelerator Or DrawItemStateSelected ) Then
eGraphicsFillRectangle ( New SolidBrush ( ColorLightYellow ) rfBound )
eGraphicsDrawString ( s New Font ( 宋体 FontStyleBold Or FontStyleUnderline ) New SolidBrush ( ColorRed ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorBlack ) ) rfBound )
eDrawFocusRectangle ( )
End If
End Sub
MenuItem的DrawItem事件处理代码之后添加下列代码下列代码是定义MenuItem的MeasureItem事件在此事件中实现设定新建菜单项的长度和高度
Private Sub MenuItem
_MeasureItem ( ByVal sender As Object
ByVal e As System
Windows
Forms
MeasureItemEventArgs ) Handles MenuItem
MeasureItem
eItemWidth =
设定菜单项的宽度
eItemHeight =
设定菜单项的高度
End Sub
在完成上述操作步骤后再在MenuItem的MeasureItem事件处理程序之后添加下列代码下列代码是定义MenuItem的DrawItem事件其功能是对打开菜单项重新绘制
Private Sub MenuItem
_DrawItem ( ByVal sender As Object
ByVal e As System
Windows
Forms
DrawItemEventArgs ) Handles MenuItem
DrawItem
Dim rfBound As RectangleF = New RectangleF ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根据DrawItemEventArgs参数获得菜单项矩形区域并存储到RectangleF类型实例中
Dim rfBound As Rectangle = New Rectangle ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根据DrawItemEventArgs参数获得菜单项矩形区域并存储到Rectangle类型实例中
Rectangle类型实例和RectangleF类型实例差不多但在后面代码中绘制菜单的函数是有区别的
Dim s As MenuItem = CType ( sender MenuItem )
Dim s As String = sText
Dim sfTemp As StringFormat = New StringFormat ( )
sfTempAlignment = StringAlignmentCenter
sfTempLineAlignment = StringAlignmentCenter
Dim rcText As RectangleF = rfBound
rcTextWidth =
eGraphicsDrawString ( s New Font ( Veranda ) New SolidBrush ( ColorBlue ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorLightGray ) ) rfBound )
If eState = ( DrawItemStateNoAccelerator Or DrawItemStateSelected ) Then
eGraphicsFillRectangle ( New SolidBrush ( ColorLightYellow ) rfBound )
eGraphicsDrawString ( s New Font ( Veranda FontStyleBold Or FontStyleUnderline ) New SolidBrush ( ColorRed ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorBlack ) ) rfBound )
eDrawFocusRectangle ( )
End If
End Sub
MenuItem的DrawItem事件处理代码之后添加下列代码下列代码是定义MenuItem的MeasureItem事件在此事件中实现设定新建菜单项的长度和高度
Private Sub MenuItem
_MeasureItem ( ByVal sender As Object
ByVal e As System
Windows
Forms
MeasureItemEventArgs ) Handles MenuItem
MeasureItem
eItemWidth =
设定菜单项的宽度
eItemHeight =
设定菜单项的高度
End Sub
在上述步骤都正确完成后本文介绍的手工绘制菜单就完成此时单击快捷键F运行程序就可以得到图所示的运行界面
六.总结
本文主要内容是介绍VBNET设计和创建菜单其中不仅介绍了使用菜单设计器来静态设计菜单还介绍了使用MainMenu类MenuItem类和ContextMenu类动态创建菜单的实现方法在动态创建时首先要了解要创建的菜单类型是下拉菜单首先要创建一个MainMenu实例是弹出菜单首先要创建一个ContextMenu实例然后根据菜单中的组成结构即菜单项中的父子关系创建出相应菜单最后就是显示出菜单如果是下拉菜单指派给Form的Menu属性如果是弹出菜单指派给可视组件或Form的ContextMenu属性这样动态创建菜单才能够显示出来动态创建菜单的工作才算完成
此外还介绍了在Visual Basic Net中绘制个性化菜单的实现方法和注意事项在绘制个性化菜单时最重要的是掌握DrawItem事件和MeasureItem事件用法及绘制菜单时所要使用到的方法虽然本文绘制的菜单并不美观但你可以通过本文介绍的方法来修改从而实现更美观更有个性的菜单最后请记住在绘制菜单时首先把菜单项的OwnerDraw属性设定为True
[] [] []