Publicado el 26/Dic/2005
Actualizado el 26/Dic/2005
Autor: Guillermo 'guille' Som
Este ejemplo usa la clase RichMenuItem para Visual Basic que te he mostrado en esta página.
Además del código de ejemplo de cómo usar la clase RichMenuItem, también te muestro una clase (MImages) con la que puedes indicar de forma fácil el icono a usar a partir de una imagen (.png) en la que hay varios iconos, dicha imagen la tendremos en el formulario que usará los menús con imágenes.
La imagen usada para obtener los iconos de los menús y usada en la clase MImages
Por ahora solo está publicada la versión para Visual Basic 2003, pero no te será complicado crear el ejemplo de C#.
Aquí tienes una captura del formulario con el menú de edición y sus gráficos:
La aplicación de ejemplo en ejecución
En el menú de estilos he añadido las opciones para cambiar a los diferentes estilos de menús soportados por la clase.
El usado de forma predeterminada el estilo: Office2003 que es el mostrado en la captura, y aunque no se vea bien, el fondo de los menús es azul claro.
En el código del formulario te muestro dos formas de crear los menús:
1- Usando los que ya estuvieran creados en tiempo de diseño.
2- Creándolos desde cero, (que es la forma usada en el código de ejemplo).Lo malo que tiene este control es que no se "integra" con el diseñador de formularios, por tanto, su uso debe ser manual, pero... si quieres gráficos en los menús... debes hacerlo manualmente o bien usar el Visual Basic 2005... pero ese no es el caso que te ha traído hasta aquí... así que... ¡a escribir código! ;-)))))
Nos vemos.
Guillermo
El código para VB .NET de la clase MImages
Este es el código de la clase MImages para extraer un icono de una imagen.
'---------------------------------------------------------------------- ' Clase MImages (19/Jun/04) ' Para las imágenes usadas en los menús. ' La imagen usada es: ImageList16Guille2.png ' ' La enumeración eImagenes indicará el índice de la imagen del bitmap ' indicado en el constructor y se podrá obtener como un Bitmap ' o como un Image usando los métodos Bitmaps o Images respectivamente. ' ' Revisado 26/Dic/2005 Para recibir la imagen en el constructor. ' ' ©Guillermo 'guille' Som, 2004-2005 '---------------------------------------------------------------------- Imports System Imports System.Drawing Public Enum eImagenes eNew eOpen eSave eCut eCopy ePaste eDelete eProperties eUndo eRedo ePreview ePrint eSearch eReSearch eHelp eZoomIn eZoomOut eBack eForward eFavorites eAddToFavorites eStop eRefresh eHome eVentanaLapiz 'Edit eVentanaTools eVentanaTiles ' 2 cuadros eVentanaIcons ' 6 cuadros eVentanaListAB ' List eVentanaDivHor 'Details eVentanaDivVer 'Pane eCulture eLanguages eHistory eMail eParent eFolderProperties ' egMsgBStop egMsgBExclamation egMsgBInfo egMsgBQuestion egMinimize egRueda egConfig1 egConfigOk egRun egCompuTeclado egStandBy egAltavoz egAltavozOff 'Ultima = egAltavozOff End Enum Public Class MImages Private mImages As Image() Private numImg As Integer ' En el constructor pasamos la imagen a usar (26/Dic/05) Public Sub New(ByVal picImageList16 As Image) Dim bmap As New Bitmap(picImageList16) numImg = CType((bmap.Width / bmap.Height), Integer) - 1 ReDim mImages(numImg) Dim rect As New Rectangle(0, 0, bmap.Height, bmap.Height) For i As Integer = 0 To numImg mImages(i) = bmap.Clone(rect, bmap.PixelFormat) rect.X += bmap.Height Next End Sub Public Function Images(ByVal index As eImagenes) As Image If index > numImg Then index = CType(numImg, eImagenes) End If Return mImages(CType(index, Integer)) End Function Public Function Bitmaps(ByVal index As eImagenes) As Bitmap If index > numImg Then index = CType(numImg, eImagenes) End If Return New Bitmap(mImages(CType(index, Integer))) End Function End Class
El código para VB .NET del formulario de ejemplo
Este es el código del formulario de ejemplo que utiliza la clase RichMenuItem con imágenes en los menús. '------------------------------------------------------------------------------ ' Ejemplo para usar RichMenuItem con imágenes (26/Dic/05) ' Usando la clase RichMenuItem y MImages. ' ' ©Guillermo 'guille' Som, 2005 '------------------------------------------------------------------------------ Option Strict On Imports Microsoft.VisualBasic Imports System Imports System.Windows.Forms Imports System.Drawing Public Class Form1 Inherits System.Windows.Forms.Form ' #Region " Código generado por el Diseñador de Windows Forms " #End Region ' Public Sub New() MyBase.New() 'El Diseñador de Windows Forms requiere esta llamada. InitializeComponent() 'Agregar cualquier inicialización después de la llamada a InitializeComponent() mimg = New MImages(picImageList16Guille2.Image) End Sub ' Private mimg As MImages ' Private Sub asignarMenus() ' Utilizamos los menús que tenemos asignados y los cambiamos por RichMenuItem ' Como vamos a asignar imágenes, hay que saber que acción efectúa cada menú, ' por tanto este método no es del todo automático... ' Pero se puede preparar para que "casi" lo sea si se siguen unas normas ' de nomenclatura. Dim mMenuP() As RichMenuItem ReDim mMenuP(MainMenu1.MenuItems.Count - 1) Dim menus() As RichMenuItem Dim n As Integer = 0 ' For Each mnuP As MenuItem In Me.MainMenu1.MenuItems ReDim menus(mnuP.MenuItems.Count - 1) Dim i As Integer = 0 For Each mnu As MenuItem In mnuP.MenuItems Dim texto As String = mnu.Text ' Por defecto convertimos el menú en RichMenuItem Dim rmnu As RichMenuItem = New RichMenuItem(texto) ' Si está en algunos de estos casos, se usará en vez del asignado antes If texto.IndexOf("Nuevo") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.eNew), texto, AddressOf mnuFicNuevo_Click, Shortcut.CtrlN, "Crea un nuevo fichero") ElseIf texto.IndexOf("Abrir") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.eOpen), texto, AddressOf mnuFicAbrir_Click, "Abre un fichero existente") ElseIf texto.IndexOf("Guardar") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.eSave), texto, AddressOf mnuFicGuardar_Click, Shortcut.CtrlG, "Guarda el contenido del fichero") ElseIf texto.IndexOf("Acerca") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.egMsgBInfo), texto, AddressOf mnuFicAcercaDe_Click, "Muestra la información Shortcut.Del la aplicación") ElseIf texto.IndexOf("Salir") > -1 Then rmnu = New RichMenuItem(texto, AddressOf mnuFicSalir_Click, "Termina el programa") ElseIf texto.IndexOf("Cor&tar") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.eCut), texto, AddressOf mnuEdiCortar_Click, Shortcut.CtrlX, "Cortar el texto seleccionado") ElseIf texto.IndexOf("Copiar") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.eCopy), texto, AddressOf mnuEdiCopiar_Click, Shortcut.CtrlC, "Copia el texto seleccionado") ElseIf texto.IndexOf("Pegar") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.ePaste), texto, AddressOf mnuEdiPegar_Click, Shortcut.CtrlV, "Pega del portapapeles") ElseIf texto.IndexOf("Deshacer") > -1 Then rmnu = New RichMenuItem(mimg.Bitmaps(eImagenes.eUndo), texto, AddressOf mnuEdiDeshacer_Click, Shortcut.CtrlZ, "Deshacer la última edición") End If ' Para mostrar la descripción del menú AddHandler rmnu.Select, AddressOf mnu_Select ' Asignamos el menú menus(i) = rmnu i += 1 Next ' Añadimos los submenús al menú mMenuP(n) = New RichMenuItem(mnuP.Text) mMenuP(n).MenuItems.AddRange(menus) n += 1 Next ' Eliminamos los que hubiera antes MainMenu1.MenuItems.Clear() ' Añadimos los nuevos menús creados MainMenu1.MenuItems.AddRange(mMenuP) End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Asignar el estilo a usar en los menús RichMenuItem.DefaultMenuStyle = IconMenuStyle.Office2003 ' '------------------------------ ' Crear los menús directamente '------------------------------ ' Habría que definir los menús y añadirlos a un objeto MainMenu ' para posteriormente asignarlo a Me.Menu Dim mMenuP() As RichMenuItem ReDim mMenuP(1) Me.Menu.MenuItems.Clear() mMenuP(0) = New RichMenuItem("&Fichero") mMenuP(1) = New RichMenuItem("&Edición") mMenuP(0).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.eNew), "&Nuevo", AddressOf mnuFicNuevo_Click, Shortcut.CtrlN, "Crea un nuevo fichero")) mMenuP(0).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.eOpen), "&Abrir", AddressOf mnuFicAbrir_Click, "Abre un fichero existente")) mMenuP(0).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.eSave), "&Guardar", AddressOf mnuFicGuardar_Click, Shortcut.CtrlG, "Guarda el contenido del fichero")) ' Incluso los separadores deben ser del tipo RichMenuItem mMenuP(0).MenuItems.Add(New RichMenuItem("-")) mMenuP(0).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.egMsgBInfo), "Acerca de...", AddressOf mnuFicAcercaDe_Click, "Muestra la información Shortcut.Del la aplicación")) mMenuP(0).MenuItems.Add(New RichMenuItem("-")) mMenuP(0).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.egStandBy), "Salir", AddressOf mnuFicSalir_Click, "Termina el programa")) ' mMenuP(1).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.eUndo), "Deshacer", AddressOf mnuEdiDeshacer_Click, Shortcut.CtrlZ, "Deshacer la última edición")) mMenuP(1).MenuItems.Add(New RichMenuItem("-")) mMenuP(1).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.eCut), "Cor&tar", AddressOf mnuEdiCortar_Click, Shortcut.CtrlX, "Cortar el texto seleccionado")) mMenuP(1).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.eCopy), "&Copiar", AddressOf mnuEdiCopiar_Click, Shortcut.CtrlC, "Copia el texto seleccionado")) mMenuP(1).MenuItems.Add(New RichMenuItem(mimg.Bitmaps(eImagenes.ePaste), "&Pegar", AddressOf mnuEdiPegar_Click, Shortcut.CtrlV, "Pega del portapapeles")) ' ' Lo asignamos al menú del formulario Me.Menu.MenuItems.AddRange(mMenuP) ' ' Si se han añadido en tiempo de diseño, se puede usar el método asignarMenus() ' Quita el comentario para usar este método y comenta el código anterior 'asignarMenus() ' ' Estos no están en tiempo de diseño ' y se añadirán seleccionemos el método que seleccionemos. ReDim mMenuP(0) mMenuP(0) = New RichMenuItem("Estilos", "Selecciona los estilos de los menús") mMenuP(0).MenuItems.Add(New RichMenuItem(IconMenuStyle.Office2000.ToString, AddressOf mnuEstilos_Select)) mMenuP(0).MenuItems.Add(New RichMenuItem(IconMenuStyle.Office2003.ToString, AddressOf mnuEstilos_Select)) mMenuP(0).MenuItems.Add(New RichMenuItem(IconMenuStyle.Standard.ToString, AddressOf mnuEstilos_Select)) mMenuP(0).MenuItems.Add(New RichMenuItem(IconMenuStyle.VSNet.ToString, AddressOf mnuEstilos_Select)) Me.Menu.MenuItems.Add(mMenuP(0)) Me.Menu.MenuItems(2).MenuItems(1).Checked = True ' ' Añadir el evento Select para mostrar la información For Each mnu As RichMenuItem In Me.Menu.MenuItems AddHandler mnu.Select, AddressOf mnu_Select For Each mnu1 As RichMenuItem In mnu.MenuItems AddHandler mnu1.Select, AddressOf mnu_Select Next Next End Sub Private Sub mnu_Select(ByVal sender As Object, ByVal e As System.EventArgs) If TypeOf sender Is RichMenuItem Then Dim s As String Dim mnu As RichMenuItem = CType(sender, RichMenuItem) s = mnu.Description If s = "" Then s = "Seleccionado: " & mnu.Text LabelStatus.Text = s End If End Sub Private Sub mnuEstilos_Select(ByVal sender As Object, ByVal e As System.EventArgs) ' Quitar las marcas For Each mnu As RichMenuItem In Me.Menu.MenuItems(2).MenuItems mnu.Checked = False Next ' Marcar el actual CType(sender, RichMenuItem).Checked = True ' Comprobar el estilo a usar Select Case CType(sender, RichMenuItem).Text Case IconMenuStyle.Office2000.ToString RichMenuItem.DefaultMenuStyle = IconMenuStyle.Office2000 Case IconMenuStyle.Office2003.ToString RichMenuItem.DefaultMenuStyle = IconMenuStyle.Office2003 Case IconMenuStyle.Standard.ToString RichMenuItem.DefaultMenuStyle = IconMenuStyle.Standard Case IconMenuStyle.VSNet.ToString RichMenuItem.DefaultMenuStyle = IconMenuStyle.VSNet End Select ' Asignar el nuevo estilo a los menús Dim estilo As IconMenuStyle = RichMenuItem.DefaultMenuStyle For Each mnu As RichMenuItem In Me.Menu.MenuItems mnu.MenuStyle = estilo For Each mnu1 As RichMenuItem In mnu.MenuItems mnu1.MenuStyle = estilo Next Next End Sub ' ' Aunque estos métodos tengan el Handles, en realidad se usa el asignado al crear el menú ' Private Sub mnuFicNuevo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFicNuevo.Click TextBox1.Text = "" End Sub Private Sub mnuFicAbrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFicAbrir.Click MsgBox(CType(sender, MenuItem).Text) End Sub Private Sub mnuFicGuardar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFicGuardar.Click MsgBox(CType(sender, MenuItem).Text) End Sub Private Sub mnuFicAcercaDe_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFicAcercaDe.Click MsgBox("Pueba de uso de la clase RichMenuItem", MsgBoxStyle.Information) End Sub Private Sub mnuFicSalir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuFicSalir.Click Me.Close() End Sub Private Sub mnuEdiDeshacer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuEdiDeshacer.Click TextBox1.Undo() End Sub Private Sub mnuEdiCortar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuEdiCortar.Click TextBox1.Cut() End Sub Private Sub mnuEdiCopiar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuEdiCopiar.Click TextBox1.Copy() End Sub Private Sub mnuEdiPegar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuEdiPegar.Click 'TextBox1.SelectedText = Clipboard.GetDataObject().GetData("System.String").ToString TextBox1.Paste() End Sub End Class