Creando Menús Dinámicos con ASP.NET
En esta entrada veremos de una manera muy sencilla como crear un menú con el control Menu de ASP.NET.
Para esta entrada crearemos una tabla en cualquier base de datos de SQL de ejemplo con el siguiente script:
CREATE TABLE [dbo].[Menu_Options]( [id_menu_option] [int] NOT NULL, [description] [varchar](50), [id_parent_menu_option] [int] NOT NULL, [url] [varchar](80))
Insertaremos en nuestra tabla los siguientes registros de ejemplo:
INSERT INTO Menu_Options (id_menu_option, description, id_parent_menu_option, url) values (1, 'Inicio', 1, '#') INSERT INTO Menu_Options (id_menu_option, description, id_parent_menu_option, url) values (2, 'Nosotros', 2, '#') INSERT INTO Menu_Options (id_menu_option, description, id_parent_menu_option, url) values (3, 'Contacto', 3, '#') INSERT INTO Menu_Options (id_menu_option, description, id_parent_menu_option, url) values (4, 'Misión', 2, 'Page1.aspx') INSERT INTO Menu_Options (id_menu_option, description, id_parent_menu_option, url) values (5, 'Visión', 2, 'Page2.aspx') INSERT INTO Menu_Options (id_menu_option, description, id_parent_menu_option, url) values (6, 'Valores', 2, 'Page3.aspx')
Crearemos un sitio Web vacío de ASP.NET con C# y agregaremos una pagina con el nombre Default.aspx en nuestra pagina agregaremos nuestro control menú y le daremos un formato automático o bien pueden dar su propio estilo, nuestro código se veria asi:
<asp:Menu ID="MyMenu" runat="server" Height="32px" Orientation="Horizontal" Width="280px" MaximumDynamicDisplayLevels ="2" BackColor="#FFFBD6" DynamicHorizontalOffset="2" Font-Names="Verdana" Font-Size="0.8em" ForeColor="#990000" StaticSubMenuIndent="10px"> <DynamicHoverStyle BackColor="#990000" ForeColor="White" /> <DynamicMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" /> <DynamicMenuStyle BackColor="#FFFBD6" /> <DynamicSelectedStyle BackColor="#FFCC66" /> <StaticHoverStyle BackColor="#990000" ForeColor="White" /> <StaticMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" /> <StaticSelectedStyle BackColor="#FFCC66" /> </asp:Menu>
Agregaremos en nuestro Web.Config nuestra cadena de conexcion como se muestra a continuación:
<connectionStrings> <add name="Server1ConnectionString" connectionString="Data Source=.;Initial Catalog=MyDynamicMenuSite;User ID=sa2" providerName="System.Data.SqlClient" /> </connectionStrings>
En el codebehind de nuestra pagina agregaremos una rutina con el nombre de BindMenuControl() la cual mandaremos llamar en el evento Page_Load de nuestra pagina, esta función realizara una consulta a nuestra base de datos la cual retornara todos los campos de la tabla que creamos anteriormente la cual contiene todos los ítems de nuestro menú y los subitems, llenaremos un dataset y utilizaremos la tabla que retornara nuestra consulta y con un ciclo empezaremos a agregar cada ítem a nuestro control Menu.
protected void BindMenuControl() { SqlConnection scSqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Server1ConnectionString"].ConnectionString.ToString()); SqlCommand scSqlCommand = new SqlCommand("SELECT id_menu_option, description, id_parent_menu_option, url FROM Menu_Options", scSqlConnection); SqlDataAdapter sdaSqlDataAdapter = new SqlDataAdapter(scSqlCommand); DataSet dsDataSet = new DataSet(); DataTable dtDataTable = null; try { scSqlConnection.Open(); sdaSqlDataAdapter.Fill(dsDataSet); dtDataTable = dsDataSet.Tables[0]; if (dtDataTable != null && dtDataTable.Rows.Count > 0) { foreach (DataRow drDataRow in dtDataTable.Rows) { if (Convert.ToInt32(drDataRow[0]) == Convert.ToInt32(drDataRow[2])) { MenuItem miMenuItem = new MenuItem(Convert.ToString(drDataRow[1]), Convert.ToString(drDataRow[0]), String.Empty, Convert.ToString(drDataRow[3])); this.MyMenu.Items.Add(miMenuItem); AddChildItem(ref miMenuItem, dtDataTable); } } } } catch (Exception ex) { Response.Write(ex.Message.ToString()); } finally { scSqlConnection.Close(); sdaSqlDataAdapter.Dispose(); dsDataSet.Dispose(); dtDataTable.Dispose(); } }
Después de esto agregaremos otra rutina con el nombre de AddChildItem la cual recibirá como referencia cada uno de los ítems padre y se llamara en nuestra función BindMenuControl, esta función es re cursiva ya que cada vez que inserte un subitem a nuestro ítem padre se volverá a ejecutar para revisar si existe un subitem del subitem que se acaba de agregar al ítem padre y repetirá esta acción las veces necesarias.
protected void AddChildItem(ref MenuItem miMenuItem, DataTable dtDataTable) { foreach (DataRow drDataRow in dtDataTable.Rows) { if (Convert.ToInt32(drDataRow[2]) == Convert.ToInt32(miMenuItem.Value) && Convert.ToInt32(drDataRow[0]) != Convert.ToInt32(drDataRow[2])) { MenuItem miMenuItemChild = new MenuItem(Convert.ToString(drDataRow[1]), Convert.ToString(drDataRow[0]), String.Empty, Convert.ToString(drDataRow[3])); miMenuItem.ChildItems.Add(miMenuItemChild); AddChildItem(ref miMenuItemChild, dtDataTable); } } }
Al ejecutar nuestra pagina nuestro menú debería lucir de la siguiente manera:
Hola como estas, podrías dar un link para la descarga de datos, tengo muchos problemas para copiarlas y pegarlas es que soy nuevo con .net
luis
17 marzo, 2011 at 6:23 PM
excelente hermano, con personas como tu desinteresada se puede avanzar. gracias mil.
ivan lora
28 marzo, 2011 at 6:24 PM
Muchisimas gracias Jonathan, agradezco la ayuda que su codigo me brindo, busque mucho porque estoy empezando con esta herramienta y la solucion que escribe es sencila, facil de enteder y funciona muy bien.. solo que reescribi un poco la instruccion «SqlConnection» para ajustarla a mi equipo… pero por lo demas muy agradecido.. Saludos
Carlos
8 octubre, 2011 at 12:58 PM
Excelente que bueno que te fue útil, saudos!
jcrappy
8 octubre, 2011 at 1:44 PM
Aportazo. Se agradece.
Man Edu
27 octubre, 2011 at 10:51 PM
excelente amigo… podrias por favor explicar mas a detalle ( aqui o en mi correo maxpoder_18@hotmail.com) lo que sucede en el evento load desde la linea 13 hasta la 25 y lo que sucede en la rutina… es que ya lo copie y pegue y funciona a las mil maravillas, pero es la primera vez q no entiendo …. gracias
abel camilo
25 febrero, 2012 at 11:49 PM