Recorrer la estructura de un menú por código
A partir de Visual Studio 2005, el diseño de menús para Windows Forms experimentó una mejora considerable gracias a la incorporación de la clase MenuStrip a la plataforma .NET, a la que acompañaban también todo el conjunto de clases relacionadas con ella: ToolStripMenuItem, ToolStripSeparator, ToolStripTextBox, etc., y que incrementaban notablemente las funcionalidades aportadas por la clase dedicada hasta ese momento a tales menesteres: MainMenu.
La creación de un menú utilizando la clase MenuStrip, nos permite definir sus opciones con características que están más allá del mero literal que muestra el título de la opción, siendo posible que su comportamiento sea el de una caja de texto o una lista desplegable.
No obstante, la finalidad del presente artículo no es mostrar las características particulares de tales tipos de opción de menú, sino exponer un ejemplo que nos permita recorrer su estructura de opciones, realizando cambios en las mismas, en función de si pertenecen a un tipo determinado o poseen ciertas características.
Para ello partiremos de un formulario al que añadiremos un menú con el conjunto de opciones que vemos en la siguiente imagen.

Entre las opciones de este menú podemos observar (indicadas con flechas en la imagen) que se encuentran dos de tipo caja de texto -objetos ToolStripTextBox-, mientras que en el resto existen algunas cuyo literal comienza por minúscula. El objetivo del proceso a desarrollar será cambiar a negrita y cursiva el tipo de letra de las opciones situadas en la barra de menú, convertir a mayúscula el contenido de las opciones de tipo ToolStripTextBox, y situar una marca de verificación junto a las opciones que empiezan por minúscula.
Dado que un menú puede organizarse -tal y como vemos en este ejemplo- en opciones que a su vez despliegan nuevos conjuntos de opciones dependientes, se hace necesario implementar un algoritmo recursivo que permita llegar a todos los niveles de submenús existentes en su estructura.
Sin embargo, antes que entrar en la creación de dicho algoritmo, nos ocuparemos de las dos opciones que se encuentran en la barra de menú, cuyo tipo de letra vamos a convertir a negrita y cursiva recorriendo la colección MenuStrip.Items como vemos a continuación. Todas las operaciones de transformación del menú las realizaremos desde el evento Click de un control Button situado en el formulario.
private void btnModificar_Click(object sender, EventArgs e)
{
// crear un nuevo tipo de letra para las opciones de la barra de menú
Font fntTipoLetra = new Font(menuStrip1.Items[0].Font.FontFamily,
menuStrip1.Items[0].Font.Size,
FontStyle.Bold | FontStyle.Italic);
// recorrer las opciones del menú
foreach (ToolStripMenuItem mnuitOpcion in this.menuStrip1.Items)
{
// cambiar el tipo de letra
mnuitOpcion.Font = fntTipoLetra;
}
}
Después de ejecutar el anterior código habremos realizado la transformación de las opciones de menú de la barra... ¡¡¡y también del resto de opciones!!! =8-O, ya que un cambio de estas características, realizado en la opción principal de la barra, se propaga al resto de opciones del mismo tipo que dicha opción despliega, por lo que las opciones de tipo ToolStripTextBox no se verán afectadas.

Puesto que solamente deseamos modificar el tipo de letra en la barra de menú, guardaremos el objeto Font original en una variable, restaurándolo al recorrer las opciones de los menús desplegables.
En lo que respecta al proceso encargado de recorrer estos menús desplegables, el modo de detectar si una opción de menú tiene un submenú asociado, pasa por comprobar su propiedad DropDownItems, la cual es una colección de objetos ToolStripItem.
private void btnModificar_Click(object sender, EventArgs e)
{
// obtener el tipo de letra original de las opciones de menú
// para restaurarlo en las opciones desplegables
Font fntOriginal = this.menuStrip1.Items[0].Font;
//....
// recorrer las opciones del menú
foreach (ToolStripMenuItem mnuitOpcion in this.menuStrip1.Items)
{
//....
// si esta opción despliega un submenú
// llamar a un método para hacer cambios
// en las opciones del submenú
if (mnuitOpcion.DropDownItems.Count > 0)
{
this.CambiarOpcionesMenu(mnuitOpcion.DropDownItems, fntOriginal);
}
}
}
Para cada opción de menú situada en la barra comprobaremos si despliega un submenú, y en caso afirmativo, llamaremos a un método con el nombre CambiarOpcionesMenu, que será ejecutado recursivamente cada vez que volvamos a encontrarnos con una opción que despliegue nuevos elementos. Este método recibirá como parámetros la colección de opciones a recorrer, y el objeto Font original a restaurar sobre las opciones.
private void CambiarOpcionesMenu(ToolStripItemCollection colOpcionesMenu, Font fntTipoOriginal)
{
// recorrer el submenú
foreach (ToolStripItem itmOpcion in colOpcionesMenu)
{
//....
// si esta opción a su vez despliega un nuevo submenú
// llamar recursivamente a este método para cambiar sus opciones
if (((ToolStripMenuItem)itmOpcion).DropDownItems.Count > 0)
{
this.CambiarOpcionesMenu(((ToolStripMenuItem)itmOpcion).DropDownItems,
fntTipoOriginal);
}
}
}
Al recorrer la colección ToolStripItemCollection, cada uno de sus elementos es un tipo de la clase base ToolStripItem. Es por ello que deberemos realizar una operación de conversión de tipos, para obtener el tipo de opción adecuado, y aplicarle los cambios pertinentes cuando sea necesario. Seguidamente podemos ver el código fuente del ejemplo al completo.
private void btnModificar_Click(object sender, EventArgs e)
{
// obtener el tipo de letra original de las opciones de menú
// para restaurarlo en las opciones desplegables
Font fntOriginal = this.menuStrip1.Items[0].Font;
// crear un nuevo tipo de letra para las opciones de la barra de menú
Font fntTipoLetra = new Font(menuStrip1.Items[0].Font.FontFamily,
menuStrip1.Items[0].Font.Size,
FontStyle.Bold | FontStyle.Italic);
// recorrer las opciones del menú
foreach (ToolStripMenuItem mnuitOpcion in this.menuStrip1.Items)
{
// cambiar el tipo de letra
mnuitOpcion.Font = fntTipoLetra;
// si esta opción despliega un submenú
// llamar a un método para hacer cambios
// en las opciones del submenú
if (mnuitOpcion.DropDownItems.Count > 0)
{
this.CambiarOpcionesMenu(mnuitOpcion.DropDownItems, fntOriginal);
}
}
}
private void CambiarOpcionesMenu(ToolStripItemCollection colOpcionesMenu, Font fntTipoOriginal)
{
// recorrer el submenú
foreach (ToolStripItem itmOpcion in colOpcionesMenu)
{
// restaurar el tipo de letra original
itmOpcion.Font = fntTipoOriginal;
// si la opción de menú es de tipo caja de texto
// pasar su contenido a mayúsculas
if (itmOpcion.GetType() == typeof(ToolStripTextBox))
{
itmOpcion.Text = itmOpcion.Text.ToUpper();
}
// si es una opción de menú normal...
if (itmOpcion.GetType() == typeof(ToolStripMenuItem))
{
// ... y el primer caracter está en minúscula
// poner en la opción una marca de verificación
if (char.IsLower(itmOpcion.Text.ToCharArray(0, 1)[0]))
{
((ToolStripMenuItem)itmOpcion).Checked = true;
}
// si esta opción a su vez despliega un nuevo submenú
// llamar recursivamente a este método para cambiar sus opciones
if (((ToolStripMenuItem)itmOpcion).DropDownItems.Count > 0)
{
this.CambiarOpcionesMenu(((ToolStripMenuItem)itmOpcion).DropDownItems,
fntTipoOriginal);
}
}
}
}
En la siguiente imagen podemos ver el resultado de ejecutar el anterior código sobre nuestro menú, con el que hemos logrado modificar dinámicamente las propiedades de sus elementos.

Los proyectos de Visual Studio con los fuentes correspondientes a este ejemplo, pueden descargarse en los siguientes enlaces para C# y VB.
Espero que os resulte de utilidad.
Un saludo.