如何建立自訂的功能表,在 Visual Basic.NET 中或在 Visual Basic 2005 中

文章翻譯 文章翻譯
文章編號: 888168 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

學習如何建立自訂功能表,在 Microsoft Visual Basic.NET 或 Microsoft Visual Basic 2005 透過討論和同時程式碼範例

簡介

本文將告訴您,如何建立自訂的功能表,在 Microsoft Visual Basic.NET 或 Microsoft Visual Basic 2005 中。藉由繼承 MainMenu 控制項以及將屬性加入至 MainMenu 控制項的項目,您可以建立自訂的功能表。

擴充 MenuItem 類別

MenuItem 類別未提供顯示圖示的內建的方法。比方說沒有 圖示 的屬性可設定要顯示的圖示。當 Microsoft.NET Framework 類別並不會提供您想要的功能時,您可以延伸該類別,並自行提供該功能。

您可以擴充 MenuItem 類別,以便您可以建立主控描繪功能表項目。開發人員是負責在螢幕上繪製 MenuItem 類別表示主控描繪功能表項目。

若要延伸 MenuItem 類別,使用下列類別繼承語法。
Public Class MyIconMenu
    Inherits MenuItem
End Class

宣告 Font 物件和 MenuItem 類別的圖示] 物件

當您從 MenuItem 類別繼承時,您可以繼承其屬性、 方法和事件。您可以為自訂類別建立您自己的圖示,藉由覆寫行為的兩個您繼承的方法。您會覆寫的 OnMeasureItem 方法和 OnDrawItem 方法的行為。您也必須宣告私用 (Private) 欄位內自訂類別來保存 字型 物件和 圖示 物件。您需要 Font 物件,以便您自訂的類別可以包含除了圖示的文字。

如果您需要一種方法的開發人員使用來初始化私用欄位的自訂類別時,使用自訂類別的建構函式。Visual Basic.NET 2003年建構函式是一種特殊方法,稱為 新增]。當您自訂的類別執行個體化,.NET Framework 會呼叫 New 方法。利用 Visual Basic.NET 2003年您可以將參數傳遞到建構函式。

Visual Basic.NET 2003年也支援方法多載。只要方法簽名碼都是唯一您可以定義指定相同的方法很多次。

藉由使用建構函式和方法多載化,您可以讓開發人員初始化自訂類別的私用欄位。自訂類別的程式碼可能會類似下列的程式碼範例。
Public Class MyIconMenu Inherits MenuItem
       	Private font As Font
        Private icon As Icon

            Sub New(ByVal menuText As String)
                   MyClass.New(menuText, Nothing, Shortcut.None, Nothing)
           	End Sub

            Sub New(ByVal menuText As String, ByVal handler As EventHandler,  ByVal shortcut As Shortcut, ByVal ico As icon)
                MyBase.New(menuText, handler, shortcut)
                Me.icon = ico
                Me.font = New Font("Arial", 8)
                Me.OwnerDraw = True
            End Sub
   End Class
請注意您有使用方法多載化您建構函式上,這樣開發人員有讓功能表項目,並附有一個圖示或功能表項目沒有圖示的。自訂類別的 [OwnerDraw 屬性也必須設定 ,則為 True 值如果您想要顯示圖示。這個步驟很重要,因為如果未完成此步驟,沒有圖示就會顯示在您的功能表。

新增至您的功能表項目

請檢查這兩個必須覆寫的方法。繪製您的功能表時,會呼叫 OnMeasureItem 方法。OnMeasureItem 方法可讓您指定您的功能表大小來設定 MeasureItemEventArgs 建構函式的兩個屬性。您設定 [MeasureItemEventArgs 建構函式的兩個屬性是 ItemHeight 屬性和 ItemWidth 屬性。這些設定會當做參數傳遞至 OnMeasureItem 方法。

若要判斷圖示的高度為基礎的功能表項目高度。這可能或可能不一定適當。通常,高度的功能表項目的文字不應超過圖示的高度。

若要判斷您的功能表寬度,您必須知道顯示在功能表項目中的字串的寬度。您可以使用 StringFormat 物件來擷取這項資訊。這個物件可以找到 System.Drawing 命名空間中。當測量的功能表項目寬度時,還必須考慮圖示。

OnMeasureItem 方法的程式碼可能類似下列程式碼範例的程式碼。
Protected Overrides Sub OnMeasureItem(ByVal e As MeasureItemEventArgs)
        MyBase.OnMeasureItem(e)
        Dim sf As StringFormat = New StringFormat()

        sf.HotkeyPrefix = HotkeyPrefix.Show
        sf.SetTabStops(50, New Single() {0})

        e.ItemHeight = Me.icon.Height + 6
        e.ItemWidth = CInt(e.Graphics.MeasureString(AppendShortcut(), _ 
                           Me.font, 1000, sf).Width) + Me.icon.Width + 5
        sf.Dispose()
        sf = Nothing
End Sub

繪製您的功能表

指定您的功能表大小之後,您必須使用自訂類別的 OnDrawItem 方法所繪製您的功能表。這個方法會傳遞給 DrawItemEventArgs 物件。您可以使用 DrawItemEventArgs 物件為功能表項目取得 圖形 物件。這讓您直接在您的功能表介面上繪製藉由使用強大 GDI + 功能在.NET Framework 中可用。第一次,繪製背景色彩。然後,繪製圖示。上次,繪製功能表項目的文字。

您的功能表的程式碼可能類似下列程式碼範例的程式碼。
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
   Dim br As Brush
   Dim sf As StringFormat

   MyBase.OnDrawItem(e)
   e.Graphics.FillRectangle(SystemBrushes.Control, e.Bounds)
   If Not (Me.icon Is Nothing) Then
      e.Graphics.DrawIcon(Me.icon, e.Bounds.Left + 3, e.Bounds.Top + 3)
   End If

   sf = New StringFormat()
   sf.HotkeyPrefix = HotkeyPrefix.Show
   sf.SetTabStops(50, New Single() {0})
   br = New SolidBrush(SystemColors.WindowText)
   e.Graphics.DrawString(AppendShortcut(), Me.font, br, e.Bounds.Left + _ 
                         Me.icon.Width + 10, e.Bounds.Top + 2, sf)
   'Clean up resources.
   br.Dispose()
   br = Nothing
   sf.Dispose()
   sf = Nothing
End Sub

建立功能表項目的鍵盤捷徑

在程式碼的範例中 OnMeasureItem 方法和 OnDrawItem 方法呼叫 AppendShortcut 函式。您可以測量並繪製您根據功能表項目] 的 [文字] 屬性的字串。不過,這不會考慮功能表項目可能具有鍵盤快速鍵。如果功能表項目沒有鍵盤快速鍵,您必須顯示鍵盤快速鍵,並增加功能表項目的寬度。您必須為字串表示鍵盤快速鍵。AppendShortcut 函式表示為字串的快速鍵,並將快顯字串附加到現有的功能表項目文字。

AppendShortcut 函式的程式碼可能會類似下列程式碼範例的程式碼。
Private Function AppendShortcut() As String
   Dim s As String
   s = Me.Text
   ' Check to see if we have a shortcut.
   ' If so, append it to our existing text.  
   If Me.ShowShortcut And Me.Shortcut <> Shortcut.None Then
      Dim k As Keys = CType(Shortcut, Keys)
      s = s & Convert.ToChar(9) & _ 
             TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k)
      End If
   Return s
End Function

反白顯示功能表項目

建立基本的圖示功能表項目之後,您可能要選取時,反白顯示功能表項目。您必須繪製一個框線,並反白顯示文字 OnDrawItem 方法中。

程式碼範例

下列的程式碼範例是完整的程式碼,為您自訂的類別。這個程式碼範例也包含程式碼,以反白顯示功能表項目。
' Form1.vb
Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()

        MyBase.New()

        'This call is required by the Windows Form Designer.

        InitializeComponent()

        'Add any initialization after the InitializeComponent() call.

    End Sub

 

    'Form overrides dispose to clean up the component list.

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

        If disposing Then

            If Not (components Is Nothing) Then

                components.Dispose()

            End If

        End If

        MyBase.Dispose(disposing)

    End Sub

 

    'Required by the Windows Form Designer.

    Private components As System.ComponentModel.IContainer

 

    'Note The following procedure is required by the Windows Form Designer.

    'It can be modified by using the Windows Form Designer.  

    'Do not modify it by using the code editor.

    Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu

    Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

        Me.MainMenu1 = New System.Windows.Forms.MainMenu

        Me.MenuItem1 = New System.Windows.Forms.MenuItem

    

        Me.MainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem1})

        Me.MenuItem1.Index = 0

        Me.MenuItem1.Text = ""

       

        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

        Me.ClientSize = New System.Drawing.Size(292, 273)

        Me.Menu = Me.MainMenu1

        Me.Name = "Form1"

        Me.Text = "Form1"

 

    End Sub

 

#End Region

 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'Loading the MyIconMenu onto the first menu in MainMenu1.

        Dim ico As Icon = New Icon("c:\GSA.ico")

        Dim fm As MyIconMenu = New MyIconMenu("Testing", Nothing, Shortcut.None, ico)

        MainMenu1.MenuItems(0).MenuItems.Add(fm)

    End Sub

 

End Class




' MyIconMenu.vb

Imports System

Imports System.ComponentModel

Imports System.Drawing

Imports System.Drawing.Drawing2D

Imports System.Drawing.Text

Imports System.Windows.Forms

 

Public Class MyIconMenu

    Inherits MenuItem

 

    Private font As font

    Private icon As icon

 

    'Set properties for border highlighting.

    Private borderWidth As Integer = 1

    Private borderColor As Color = Color.DarkBlue

 

 

    Sub New(ByVal menuText As String, ByVal handler As EventHandler, _

            ByVal shortcut As Shortcut, ByVal ico As icon)

 

        MyBase.New(menuText, handler, shortcut)

        Me.icon = ico

        Me.font = New Font("Arial", 8)

        Me.OwnerDraw = True

 

    End Sub

 

    Public Overloads Sub Dispose()

 

        Me.font.Dispose()

        Me.font = Nothing

        Me.icon.Dispose()

        Me.icon = Nothing

        MyBase.Dispose()

 

    End Sub

 

    Protected Overrides Sub OnMeasureItem(ByVal e As MeasureItemEventArgs)

 

        MyBase.OnMeasureItem(e)

        Dim sf As StringFormat = New StringFormat

 

        sf.HotkeyPrefix = HotkeyPrefix.Show

        sf.SetTabStops(50, New Single() {0})

 

        e.ItemHeight = Me.icon.Height + 6

        e.ItemWidth = CInt(e.Graphics.MeasureString(AppendShortcut(), _

                           Me.font, 1000, sf).Width) + Me.icon.Width + 5

 

        sf.Dispose()

        sf = Nothing

 

    End Sub

 

    Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)

 

        Dim br As Brush

        Dim sf As StringFormat

 

        MyBase.OnDrawItem(e)

 

        If CBool(e.State And DrawItemState.Selected) Then

            'Draw a border to highlight the menu.

            e.Graphics.FillRectangle(SystemBrushes.HighlightText, _

                                     e.Bounds)

 

            ControlPaint.DrawBorder(e.Graphics, e.Bounds, _

                                    Me.borderColor, Me.borderWidth, _

                                    ButtonBorderStyle.Solid, _

                                    Me.borderColor, Me.borderWidth, _

                                    ButtonBorderStyle.Solid, _

                                    Me.borderColor, Me.borderWidth, _

                                    ButtonBorderStyle.Solid, _

                                    Me.borderColor, Me.borderWidth, _

                                    ButtonBorderStyle.Solid)

 

        Else

            e.Graphics.FillRectangle(SystemBrushes.Control, e.Bounds)

        End If

 

        If Not (Me.icon Is Nothing) Then

            e.Graphics.DrawIcon(Me.icon, e.Bounds.Left + 3, _

                                e.Bounds.Top + 3)

        End If

 

        sf = New StringFormat

        sf.HotkeyPrefix = HotkeyPrefix.Show

        sf.SetTabStops(50, New Single() {0})

        br = New SolidBrush(SystemColors.WindowText)

        e.Graphics.DrawString(AppendShortcut(), Me.font, br, _

                              e.Bounds.Left + Me.icon.Width + 10, _

                              e.Bounds.Top + 2, sf)

 

        'Clean up resources.

        br.Dispose()

        br = Nothing

        sf.Dispose()

        sf = Nothing

 

    End Sub

 

    Private Function AppendShortcut() As String

 

        Dim s As String

        s = Me.Text

 

        ' Check to see if we have a shortcut.

        ' If so, append it to our existing text.  

        If Me.ShowShortcut And Me.Shortcut <> Shortcut.None Then

            ' Use TypeDescriptor to get a string representation of a

            ' Shortcut class.

             Dim k As Keys = CType(Shortcut, Keys)

 

            s = s & Convert.ToChar(9) & _

            TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k)

        End If

        Return s

    End Function

 

End Class
附註 您必須變更程式碼,在 Visual Basic 2005 中的。當您建立 Windows Form 專案時,預設值,Visual Basic 會建立兩個專案檔案。如果表單名為 Form1,代表表單的兩個檔案被命名 Form1.vb 並 Form1.Designer.vb。Form1.vb 檔案中撰寫程式碼。Windows Form 設計工具將 Form1.Designer.vb 檔案中寫入程式碼。Windows Form 設計工具會使用部分關鍵字,Form1 實作分成兩個獨立的檔案。這種行為可以防止設計工具產生的程式碼正在與您的程式碼位置顛倒。

如需有關新的 Visual Basic 2005 語言加強功能的詳細資訊,請造訪下列 Microsoft 開發 o 人 h 員 ? 工 u 具 ? 網路 (MSDN) 網站]:
http://msdn2.microsoft.com/en-us/library/ms379584(vs.80).aspx
如需有關部分類別和 Windows Form 設計工具的詳細資訊,請造訪下列 MSDN 網站:
http://msdn2.microsoft.com/en-us/library/ms171843.aspx

屬性

文章編號: 888168 - 上次校閱: 2007年5月11日 - 版次: 2.5
這篇文章中的資訊適用於:
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
關鍵字:?
kbmt kbvs2005swept kbvs2005applies kbhowtomaster kbprogramming kbmacroexample kbexpertiseinter kbhowto KB888168 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:888168
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com