Hasta ahora hemos visto la capacidad de definir menús estáticos y cómo ejecutar código en respuesta a la selección de los diferentes elementos. Es decir, que el Editor de Menús y la asignación a las ventanas de las barras de menús añadidas al proyecto implican que conocemos de antemano cuales son las opciones que deseamos presentar.
Sin embargo, lo más probable es que también estés interesado en crear y mostrar (o eliminar) opciones de menú sobre la marcha, en función por ejemplo de cuál sea un tipo de licencia, de la cantidad de elementos disponibles o bien para mostrar en un submenú de Elementos Recientes cuáles han sido los últimos archivos abiertos, así como para mostrar opciones de menú que no se pueden anticipar hasta el mismo momento en el que se ejecute la aplicación.
Para estos y otros casos, Xojo también permite crear elementos de menú de forma dinámica; e incluso la capacidad de crear completas barras de menús que podemos asignar en tiempo de ejecución a cualquiera de las instancias de ventana o al objeto App.
Puesto que una Barra de Menús precisa de Elementos de Menú, comenzaremos en primer lugar por crear los elementos de menú.
Todos los elementos de menú se crean por omisión a partir de la clase MenuItem, de modo que por ejemplo el siguiente código insertado en el Evento Open del objeto App se encargaría de añadir un nuevo elemento de menú con el nombre MiMenu
, el texto visible “Mi Opción de Menú” y el atajo de teclado “Cmd-U”:
Dim newMenuItem As New MenuItem newMenuItem.Name = "MiMenu" newMenuItem.Text = "Mi Opción de Menú" newMenuItem.KeyboardShortcut = "cmd-U"
Opcionalmente, también podríamos ahorrar algún paso utilizando el Constructor de clase y omitiendo asignar un nombre al item, aunque probablemente querrás hacerlo para simplificar algunas operaciones, tal y como veremos un poco más adelante. El siguiente código sería equivalente y más conciso:
Dim newMenuItem As New MenuItem("Mi Opción de Menú") newMenuItem.kKeyBoardShortcut = "cmd-u"
Sin embargo, el hecho de crear un nuevo ítem de menú no implica que este vaya a mostrarse sin más en una barra de menú como una entrada de primer nivel, o bien que se añada sobre cualquiera de los otros elementos de menú disponibles, ya sea cualquier elemento de menú de primer nivel ya definido en la barra de menús o bien un submenú.
Por ejemplo, si tomamos como caso la barra de menús que crea Xojo por omisión en los proyectos de escritorio, la siguiente línea se encargará de añadir el elemento de menú que hemos creado como una nueva entrada de primer nivel al final del todo; es decir, como el último elemento mostrado en el extremo derecho del menú:
Me.MenuBar.Append newMenuItem
Adicionalmente, también podemos indicar la posición exacta sobre la que deseamos que se muestre empleando el método Insert
, y que espera que le indiquemos como primer parámetro el índice basado en 0 como primera posición. Por ejemplo, si deseamos que sea la primera entrada visible desde la izquierda del menú utilizaríamos el siguiente código:
Me.MenuBar.Insert(0, newMenuItem)
Si ejecutas estos ejemplos en macOS observarás que prescinde de mostrar el atajo de teclado asignado, lo cual tiene todo el sentido del mundo; mientras que si los ejecutas en Windows comprobarás que se mostrará el atajo de teclado y que, de hecho, también respondería al atajo de teclado en el caso de que tuviese asignado un Manejador de Menú. Por tanto, dado que probablemente no querrás que esto ocurra en tus aplicaciones es recomendable utilizar elementos de menú específicos para primer nivel en los que no se usen atajos de teclado.
Prueba ahora el siguiente código tanto en macOS como en Windows y/o Linux:
Dim newMenuItem As New MenuItem("Mi Opción de Menú") Me.MenuBar.Append newMenuItem Me.MenuBar.Insert(0, newMenuItem)
Cuando ejecutes el anterior código sobre macOS comprobarás que se produce una salida inesperada de la aplicación, con el siguiente mensaje de error:
Esto se debe a que en las aplicaciones para macOS no se puede utilizar un mismo Menu Item duplicado. Sin embargo, tanto en Windows como en Linux no tendrás ningún problema a la hora de utilizar un mismo Menu Item en el mismo o diferentes menús. Si por cualquier motivo deseas utilizar el mismo Menu Item en macOS, entonces la solución a este problema pasa por utilizar el método Clone.
Como puedes imaginar, mediante el método Clone se clona el elemento de menú sobre el cual se aplica, lo cual es especialmente útil dado que podemos clonar jerarquías enterás cuando se aplica a los menús de primer nivel o a los submenús… ¡pero no a las barras de menú!
Por ejemplo, el siguiente código resolverá el anterior problema; de modo que el mismo código funcionará sin modificaciones bajo los tres sistemas operativos soportados:
Dim newMenuItem As New MenuItem("Mi Opción de Menú") Me.MenuBar.Append newMenuItem Me.MenuBar.Insert(0, newMenuItem.clone)