Cómo crear un menú personalizado en Visual Basic .NET o Visual Basic 2005

Seleccione idioma Seleccione idioma
Id. de artículo: 888168 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

Aprenda a crear un menú personalizado en Microsoft Visual Basic .NET o Microsoft Visual Basic 2005 a través de discusiones y ejemplos de código.

INTRODUCCIÓN

En este artículo se describe cómo crear un menú personalizado en Microsoft Visual Basic .NET o en Microsoft Visual Basic 2005. Crear un menú personalizado heredando el control MainMenu y agregar propiedades a los elementos del control MainMenu .

Extender la clase MenuItem

La clase MenuItem no proporciona un medio integrado de mostrar un icono. Por ejemplo, no hay ninguna propiedad de icono que se puede establecer para mostrar un icono. Cuando una clase de Microsoft .NET Framework no proporciona una característica que desea, puede extender dicha clase y puede proporcionar la característica.

Puede extender la clase MenuItem para que pueda crear un elemento de menú dibujado por el propietario. Un elemento de menú dibujado por el propietario significa que el programador es responsable de dibujar la clase MenuItem en la pantalla.

Para extender la clase MenuItem , utilice la siguiente sintaxis de herencia de clase.
Public Class MyIconMenu
    Inherits MenuItem
End Class

Declare un objeto Font y un objeto Icon de la clase MenuItem

Al heredar de la clase MenuItem , se heredan sus propiedades, métodos y eventos. Puede crear su propio icono para la clase personalizada reemplazando el comportamiento de dos de los métodos que se heredan. Reemplazar el comportamiento del método OnMeasureItem y el método OnDrawItem . También debe declarar campos privados dentro de su clase personalizada para contener una fuente y un objeto de icono . Es necesario un objeto de fuente para que la clase personalizada puede contener texto además de iconos.

Si necesita un modo para programadores que utilizan la clase personalizada para inicializar los campos privados, utilice el constructor de la clase personalizada. Un constructor de Visual Basic .NET 2003 es un método especial que se llama de nuevo . El método New llaman de .NET Framework al crear instancias de la clase personalizada. Utilizando Visual Basic .NET 2003, puede pasar parámetros a su constructor.

Visual Basic .NET 2003 también admite la sobrecarga de método. Puede definir el mismo método muchas veces, siempre y cuando las firmas de método son únicas.

Mediante constructores y sobrecarga de método, puede permitir que los desarrolladores de inicializar los campos privados de la clase personalizada. El código de la clase personalizada puede ser similar al ejemplo de código siguiente se.
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
Observe que ha utiliza el método sobrecarga en el constructor para que el desarrollador tenga la opción de tener un elemento de menú con un icono o un elemento de menú sin icono. También debe establecer la propiedad OwnerDraw de la clase personalizada en el valor true si desea mostrar un icono. Este paso es importante porque si no se ha completado este paso, iconos no se muestran en el menú.

Agregar elementos al menú

Examine los dos métodos que deben reemplazarse. Se llama al método OnMeasureItem cuando se dibuja en el menú. El método OnMeasureItem permite especificar el tamaño del menú estableciendo dos propiedades del constructor MeasureItemEventArgs . Las dos propiedades del constructor MeasureItemEventArgs que establezca son la propiedad ItemHeight y la propiedad ItemWidth . Estos valores se pasan como parámetros al método OnMeasureItem .

Quizás desee determinar el alto del elemento de menú según el alto del icono. Esto puede o no siempre es adecuado. Normalmente, el alto del texto del elemento de menú no debe superar el alto del icono.

Para determinar el ancho del menú, debe conocer el ancho de la cadena que se muestra en el elemento de menú. Puede utilizar el objeto StringFormat para recuperar esta información. Este objeto puede encontrarse en el espacio de nombres System.Drawing . Al medir el ancho del elemento de menú, también debe considerar el icono.

El código para el método OnMeasureItem puede ser similar al siguiente ejemplo de código.
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

Dibujar en el menú

Después de especificar el tamaño de su menú, debe dibujar el menú utilizando el método OnDrawItem de la clase personalizada. Este método se pasa al objeto DrawItemEventArgs . Puede utilizar el objeto DrawItemEventArgs para obtener un objeto Graphics para un elemento de menú. Esto le permite dibujar directamente en la superficie del menú utilizando las eficaces características GDI + que están disponibles en .NET Framework. En primer lugar, dibuje un color de fondo. A continuación, dibuje el icono. Por último, dibujar el texto del elemento de menú.

El código para el menú puede ser similar al siguiente ejemplo de código.
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

Crear un método para el elemento de menú abreviado de teclado

En los ejemplos de código, se llama a la función AppendShortcut en el método OnMeasureItem y el método OnDrawItem . Puede medir y dibujar la cadena según la propiedad de texto del elemento de menú. Sin embargo, esto no considera el hecho de que el elemento de menú puede tener un método abreviado de teclado. Si el elemento de menú tiene un método abreviado de teclado, debe mostrar el método abreviado de teclado y aumentar el ancho del elemento de menú. El método abreviado de teclado debe representar como una cadena. La función de AppendShortcut representa el método abreviado de teclado como una cadena y anexa la cadena de acceso directo al texto del elemento de menú existente.

El código de la función AppendShortcut puede ser similar al siguiente ejemplo de código.
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

Resalte el elemento de menú

Después de crear un elemento de menú de icono básico, puede que desee resaltar el elemento de menú cuando se selecciona. Debe dibujar un borde y resalte el texto en el método OnDrawItem .

Ejemplo de código

En el ejemplo de código siguiente se es el código completo para la clase personalizada. Este ejemplo de código incluye el código para resaltar el elemento de menú.
' 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
Nota se debe cambiar el código en Visual Basic 2005. De forma predeterminada, Visual Basic crea dos archivos para el proyecto cuando se crea un proyecto de formularios Windows Forms. Si el formulario se denomina Form1, los dos archivos que representan el formulario se denominan Form1.vb y Form1.Designer.vb. Escribir el código en el archivo Form1.vb. El Diseñador de Windows Forms escribe el código en el archivo Form1.Designer.vb. El Diseñador de Windows Forms se utiliza la palabra clave partial para dividir la implementación de Form1 en dos archivos independientes. Este comportamiento evita que el código generado por diseñador se mezcle suyo con su código.

Para obtener más información acerca de las nuevas mejoras del lenguaje Visual Basic 2005, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):
http://msdn2.microsoft.com/en-us/library/ms379584(vs.80).aspx
Para obtener más información acerca de las clases parciales y el Diseñador de Windows Forms, visite el siguiente sitio Web de MSDN:
http://msdn2.microsoft.com/en-us/library/ms171843.aspx

Propiedades

Id. de artículo: 888168 - Última revisión: viernes, 11 de mayo de 2007 - Versión: 2.5
La información de este artículo se refiere a:
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
Palabras clave: 
kbmt kbvs2005swept kbvs2005applies kbhowtomaster kbprogramming kbmacroexample kbexpertiseinter kbhowto KB888168 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 888168

Enviar comentarios

 

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