如何创建自定义菜单,在 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 控件的项目,您可以创建自定义菜单。

扩展菜单项类

菜单项 类不提供一种内置显示图标。例如对于没有 图标 属性,您可以设置为显示图标。如果 Microsoft.net 框架类不能提供所需的功能,您可以扩展该类别,并自己提供该功能。

可以将 菜单项 类扩展,因此,您可以创建所有者描述的菜单项。所有者描述的菜单项意味着开发人员负责在屏幕上绘制 菜单项 类。

若要扩展 菜单项 类,使用下面的类继承语法。
Public Class MyIconMenu
    Inherits MenuItem
End Class

声明一个 Font 对象,对象和菜单项类的对象图标

当您从该 菜单项 的类继承时,您继承了其属性、 方法,和事件。通过重写两个继承的方法的行为,您可以为您的自定义类中创建自己的图标。您重写和 OnDrawItem 方法的 OnMeasureItem 方法的行为。您还必须以容纳 字体 将自定义类中声明私有字段的对象和一个 图标 的对象。您需要一个 Font 对象,以便将自定义类可以包含除了图标的文本。

如果您需要一种方法来初始化您的私有字段使用自定义类的开发人员,使用自定义类的构造函数。Visual Basic.net 2003年构造函数是一种特殊的方法称为 新建 的。将自定义类被实例化时,将由.net 框架调用 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
请注意您必须使用方法重载在您的构造函数,以便开发人员必须有一个带图标的菜单项或没有图标的菜单项的选项。如果要显示的图标,您还必须为 true 的值设置 OwnerDraw 属性自定义类。此步骤很重要,因为如果不完成该步骤,,在您菜单上不显示任何图标。

将项目添加到您的菜单

检查这两种方法必须被重写。绘制您的菜单时调用 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 框架中可用。第一次,绘制背景色。然后,绘制图标。最后一次,绘制菜单项的文本。

您的菜单的代码可能类似于下面的代码示例。
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

创建键盘快捷方式菜单项

在代码示例 AppendShortcut 函数称为 OnMeasureItem 方法和 OnDrawItem 方法中。此时,可以测量,绘制您根据菜单项的 Text 属性的字符串。但是,这不会考虑这一事实菜单项可能有键盘快捷方式。如果菜单项具有键盘快捷方式,您必须显示键盘快捷方式,并增加菜单项的宽度。您必须作为一个字符串,表示该键盘快捷方式。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 中的代码。默认状态下,Visual Basic 创建项目的两个文件,当您创建一个 Windows 窗体项目时。如果窗体名为 Form1,Form1.vb 和 Form1.Designer.vb,被命名为表示窗体的两个文件。在 Form1.vb 文件中编写代码。Windows 窗体设计器在 Form1.Designer.vb 文件中写入代码。Windows 窗体设计器使用 partial 关键字将 Form1 的实现划分为两个单独的文件。此行为可防止该设计器生成的代码正在与您的代码交错。

有关新的 Visual Basic 2005 语言增强功能的详细信息,请访问下面的 Microsoft 开发人员网络 (MSDN) 的网站:
http://msdn2.microsoft.com/en-us/library/ms379584(vs.80).aspx
有关分部类和 Windows 窗体设计器的详细信息请访问下面的 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 标准版
  • Microsoft Visual .NET 2002 标准版
关键字:?
kbmt kbvs2005swept kbvs2005applies kbhowtomaster kbprogramming kbmacroexample kbexpertiseinter kbhowto KB888168 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 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