五.繪制個性化菜單:
先執行以下操作步驟,下列步驟是通過菜單編輯器設計一個簡單的菜單,為后面重新繪制做基礎:
1. 啟動Visual Studio .Net。
2. 選擇菜單【文件】|【新建】|【項目】后,彈出【新建項目】對話框。
3. 將【項目類型】設置為【Visual Basic項目】。
4. 將【模板】設置為【Windows應用程序】。
5. 在【名稱】文本框中輸入【自己畫菜單】。
6. 在【位置】的文本框中輸入【E:\VS.NET項目】,然后單擊【確定】按鈕,這樣在“E:\VS.NET項目”目錄中就產生了名稱為“自己畫菜單”的文件夾,并在里面創建了名稱為“自己畫菜單”的項目文件。
7. 把Visual Studio .Net的當前窗口切換到【Form1.vb(設計)】窗口,并從【工具箱】中的【Windows窗體組件】選項卡中往Form1窗體中拖入下列組件:
一個MainMenu組件,名稱為“MainMenu1”。
8. 選中“MainMenu1”組件,單擊鼠標右鍵,在彈出的菜單中選擇“編輯菜單”。并按照圖01所示界面設計菜單:
圖07:【自己畫菜單】項目設計界面之一
9. 此時保存上述步驟,并單擊快捷鍵F5,則得到圖08所示界面:
圖08:【自己畫菜單】運行界面之一
這樣通過菜單編輯器就完成了一個非常普通的菜單,下面就對此菜單進行改造,在改造之前,要先設定項目中的三個MenuItem類實例的OwnerDraw屬性值為“True”。因為只有此屬性值為“True”才會觸發繪制菜單時所需要的DrawItem事件和MeasureItem事件。之后再在上面項目的基礎上執行下一步操作:
把Visual Stuido .Net的當前窗口切換到Form1.vb的代碼編輯窗口,并在InitializeComponent過程之后添加下列代碼,下列代碼是繪制“文件”菜單項,其作用是改變“文件”菜單項的字體、大小和菜單項的,其具體的繪制方法請參考下列代碼中的注釋:
Private Sub MenuItem1_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs ) Handles MenuItem1.DrawItem
Dim rfBound As RectangleF = New RectangleF ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height )
'根據DrawItemEventArgs參數獲得菜單項矩形區域并存儲到RectangleF類型實例中
Dim rfBound1 As Rectangle = New Rectangle ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height )
'根據DrawItemEventArgs參數獲得菜單項矩形區域并存儲到Rectangle類型實例中
'Rectangle類型實例和RectangleF類型實例差不多,但在后面代碼中繪制菜單的函數是有區別的
e.Graphics.FillRectangle(New SolidBrush(Color.LightGreen), rfBound)
'以LightGreen色彩填充MenuItem1菜單項對應的矩形區域
Dim s As MenuItem = CType ( sender , MenuItem )
Dim s1 As String = s.Text
'獲得MenuItem1菜單項的名稱
Dim sfTemp As StringFormat = New StringFormat ( )
sfTemp.Alignment = StringAlignment.Center
'設定要畫的菜單名稱的對齊方式,中間對齊
e.Graphics.DrawString ( s1 , New Font ( "宋體" , 10 , FontStyle.Bold ) , New SolidBrush ( Color.Black ) , rfBound , sfTemp )
'以中間對齊方式、指定字體、大小,在指定的矩形區域重畫菜單
If e.State = ( DrawItemState.NoAccelerator Or DrawItemState.Selected ) Then
'根據菜單項的當前繪制狀態來繪制菜單項
e.Graphics.FillRectangle ( New SolidBrush ( Color.LightYellow ) , rfBound )
'對菜單項所在的矩形區域進行色彩填充
e.Graphics.DrawString ( s1 , New Font ( "宋體" , 10 , FontStyle.Bold ) , New SolidBrush ( Color.Black ) , rfBound , sfTemp )
'對菜單項名稱繪制
End If
e.DrawFocusRectangle ( )
'在 DrawItemEventArgs參數得到矩形范圍內繪制聚焦框。
e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.Black ) , 1 ) , rfBound1 )
'對菜單項的矩形區域繪制矩形框
End Sub
操作完成后,保存修改。此時再單擊快捷鍵F5運行程序,可得到如圖09所示的界面:
圖09:【自己畫菜單】運行界面之二
可見繪制的“文件”菜單項并沒有完全顯示出來,并且后面的菜單項也沒有顯示。這是因為菜單項的顯示區域并沒有設定,而缺省的空間又不能完全顯示造成的。設定菜單項的顯示區域大小是通過MeasureItem事件來完成的。具體操作是在MenuItem1的DrawItem事件后添加下列代碼,下列代碼是是定義MenuItem1的MeasureItem事件,在此事件中設定菜單項的寬度(當然也可以設定高度等):
Private Sub MenuItem1_MeasureItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.MeasureItemEventArgs ) Handles MenuItem1.MeasureItem
e.ItemWidth = 60
'設定菜單項的寬度
End Sub
保存上述修改后,單擊快捷鍵F5運行程序可得到圖10所示界面:
圖10:【自己畫菜單】運行界面之三
可見“文件”菜單項就算繪制出來了,由于其他菜單項沒有繪制處理,所以也未顯示。其他菜單項的繪制方法和“文件”菜單項的繪制方法基本相似,以下是在上述完成的基礎上,對其他菜單項進行繪制,從而得到圖11所示菜單的具體實現步驟:
圖11:【自己畫菜單】運行界面之四
1. 在Form1.vb中的MenuItem1的MeasureItem事件處理程序之后添加下列代碼,下列代碼是定義MenuItem2的DrawItem事件,其功能是對“新建”菜單項重新繪制:
Private Sub MenuItem2_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs ) Handles MenuItem2.DrawItem Dim rfBound As RectangleF = New RectangleF ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height ) '根據DrawItemEventArgs參數獲得菜單項矩形區域并存儲到RectangleF類型實例中 Dim rfBound1 As Rectangle = New Rectangle ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height ) '根據DrawItemEventArgs參數獲得菜單項矩形區域并存儲到Rectangle類型實例中 'Rectangle類型實例和RectangleF類型實例差不多,但在后面代碼中繪制菜單的函數是有區別的 e.Graphics.FillRectangle ( New SolidBrush ( Color.LightGray ) , rfBound ) Dim s As MenuItem = CType ( sender , MenuItem ) Dim s1 As String = s.Text '獲得菜單項對應的文本名稱 Dim sfTemp As StringFormat = New StringFormat ( ) sfTemp.Alignment = StringAlignment.Center '設定文本在矩形區域的對齊方式 sfTemp.LineAlignment = StringAlignment.Center Dim rcText As RectangleF = rfBound rcText.Width -= 5 e.Graphics.DrawString ( s1 , New Font ( "宋體" , 10 ) , New SolidBrush ( Color.Blue ) , rcText , sfTemp ) e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.LightGray ) ) , rfBound1 ) If e.State = ( DrawItemState.NoAccelerator Or DrawItemState.Selected ) Then e.Graphics.FillRectangle ( New SolidBrush ( Color.LightYellow ) , rfBound ) e.Graphics.DrawString ( s1 , New Font ( "宋體" , 10 , FontStyle.Bold Or FontStyle.Underline ) , New SolidBrush ( Color.Red ) , rcText , sfTemp ) e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.Black ) ) , rfBound1 ) e.DrawFocusRectangle ( ) End If End Sub |
2. MenuItem2的DrawItem事件處理代碼之后添加下列代碼,下列代碼是定義MenuItem2的MeasureItem事件,在此事件中實現設定“新建”菜單項的長度和高度:
Private Sub MenuItem2_MeasureItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.MeasureItemEventArgs ) Handles MenuItem2.MeasureItem e.ItemWidth = 60 '設定菜單項的寬度 e.ItemHeight = 30 '設定菜單項的高度 End Sub |
3. 在完成上述操作步驟后,再在MenuItem2的MeasureItem事件處理程序之后添加下列代碼,下列代碼是定義MenuItem3的DrawItem事件,其功能是對“打開”菜單項重新繪制:
Private Sub MenuItem3_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs ) Handles MenuItem3.DrawItem Dim rfBound As RectangleF = New RectangleF ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height ) '根據DrawItemEventArgs參數獲得菜單項矩形區域并存儲到RectangleF類型實例中 Dim rfBound1 As Rectangle = New Rectangle ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height ) '根據DrawItemEventArgs參數獲得菜單項矩形區域并存儲到Rectangle類型實例中 'Rectangle類型實例和RectangleF類型實例差不多,但在后面代碼中繪制菜單的函數是有區別的 Dim s As MenuItem = CType ( sender , MenuItem ) Dim s1 As String = s.Text Dim sfTemp As StringFormat = New StringFormat ( ) sfTemp.Alignment = StringAlignment.Center sfTemp.LineAlignment = StringAlignment.Center Dim rcText As RectangleF = rfBound rcText.Width -= 5 e.Graphics.DrawString ( s1 , New Font ( "Veranda" , 10 ) , New SolidBrush ( Color.Blue ) , rcText , sfTemp ) e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.LightGray ) ) , rfBound1 ) If e.State = ( DrawItemState.NoAccelerator Or DrawItemState.Selected ) Then e.Graphics.FillRectangle ( New SolidBrush ( Color.LightYellow ) , rfBound ) e.Graphics.DrawString ( s1 , New Font ( "Veranda" , 10 , FontStyle.Bold Or FontStyle.Underline ) , New SolidBrush ( Color.Red ) , rcText , sfTemp ) e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.Black ) ) , rfBound1 ) e.DrawFocusRectangle ( ) End If End Sub |
4. MenuItem3的DrawItem事件處理代碼之后添加下列代碼,下列代碼是定義MenuItem3的MeasureItem事件,在此事件中實現設定“新建”菜單項的長度和高度:
Private Sub MenuItem3_MeasureItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.MeasureItemEventArgs ) Handles MenuItem3.MeasureItem e.ItemWidth = 60 '設定菜單項的寬度 e.ItemHeight = 30 '設定菜單項的高度 End Sub |
在上述步驟都正確完成后,本文介紹的手工繪制菜單就完成,此時單擊快捷鍵F5運行。程序就可以得到圖11所示的運行界面。
六.總結:
本文主要內容是介紹VB.NET設計和創建菜單,其中不僅介紹了使用菜單設計器來靜態設計菜單,還介紹了使用MainMenu類、MenuItem類和ContextMenu類動態創建菜單的實現方法。在動態創建時,首先要了解要創建的菜單類型,是下拉菜單,首先要創建一個MainMenu實例;是彈出菜單,首先要創建一個ContextMenu實例。然后根據菜單中的組成結構,即菜單項中的父子關系,創建出相應菜單,最后就是顯示出菜單,如果是下拉菜單,指派給Form的Menu屬性,如果是彈出菜單,指派給可視組件或Form的ContextMenu屬性,這樣動態創建菜單才能夠顯示出來,動態創建菜單的工作才算完成。
此外還介紹了在Visual Basic .Net中繪制個性化菜單的實現方法和注意事項,在繪制個性化菜單時最重要的是掌握DrawItem事件和MeasureItem事件用法,及繪制菜單時所要使用到的方法,雖然本文繪制的菜單并不美觀,但你可以通過本文介紹的方法來修改,從而實現更美觀、更有個性的菜單。最后請記住,在繪制菜單時,首先把菜單項的“OwnerDraw”屬性設定為“True”。
文章來源于領測軟件測試網 http://www.kjueaiud.com/