Ver Mensaje Individual
  #2 (permalink)  
Antiguo 21/07/2007, 16:28
Avatar de zacktagnan
zacktagnan
 
Fecha de Ingreso: abril-2005
Mensajes: 501
Antigüedad: 19 años, 10 meses
Puntos: 3
Re: Construir una lista dinámicamente

Bueno, parece que la solución a lo que planteo puede pasar por utilizar el control Menu de Visual Studio 2005.

He encontrado un ejemplo aquí:
http://www.netveloper.com/contenido2.aspx?IDC=145_0

He bajado el código que está hecho con lenguaje VisualBasic.

La página .aspx lleva el control Menu de la siguiente manera:
Código:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Página sin título</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Menu ID="mnuPrincipal" runat="server" BackColor="#B1C3D9" Font-Names="Verdana"
            ForeColor="#336699" Height="20px" MaximumDynamicDisplayLevels="2" Orientation="Horizontal"
            DynamicHorizontalOffset="2" Font-Bold="True" Font-Size="11px" StaticSubMenuIndent=""
            BorderColor="#336699" BorderStyle="Solid" BorderWidth="1px">
            <DynamicMenuStyle BackColor="#B1C3D9" BorderWidth="1px" BorderColor="#336699" Width="180px" />
	        <DynamicMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" />
	        <DynamicHoverStyle ForeColor="White" Font-Bold="True" BackColor="#336699" />
            <StaticMenuStyle BackColor="#B1C3D9" BorderWidth="1px" BorderColor="#336699" />
	        <StaticMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" Width="180px" />
	        <StaticHoverStyle ForeColor="White" Font-Bold="True" BackColor="#336699" />
        </asp:Menu>
    </div>
    </form>
</body>
</html>
En la parte .aspx.vb, lleva lo siguiente:
Código:
Imports System.Data
Imports System.Data.SqlClient

Partial Class Default
    Inherits System.Web.UI.Page

    'DEFINIENDO LA CONEXIÓN
    Dim cnDatos As New SqlConnection("server=NOMBRE_SERVIDOR;database=DBApp;uid=sa")

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            'RECOGIENDO LOS DATOS DE LA BASE DE DATOS
            Dim dtMenuItems As New DataTable
            'INVOCANDO AL PROCEDIMIENTO ALMACENADO
            Dim daMenu As New SqlDataAdapter("ObtenerOpcionesMenu", cnDatos)
            daMenu.SelectCommand.CommandType = CommandType.StoredProcedure
            'LLENANDO EL DataTable
            daMenu.Fill(dtMenuItems)
            'RECORRIENDO EL DataTable PARA AGREGAR LOS ELEMENTOS QUE ESTARÁN EN LA CABECERA DEL MENÚ
            For Each drMenuItem As Data.DataRow In dtMenuItems.Rows
                'ESTA CONDICION INDICA QUE SON ELEMENTOS PADRE
                If (drMenuItem("MenuId").Equals(drMenuItem("PadreId"))) Then
                    Dim mnuMenuItem As New MenuItem
                    mnuMenuItem.Value = drMenuItem("MenuId").ToString
                    mnuMenuItem.Text = drMenuItem("Descripcion").ToString
                    mnuMenuItem.ImageUrl = drMenuItem("Icono").ToString
                    mnuMenuItem.NavigateUrl = drMenuItem("Url").ToString
                    'AGREGANDO EL ITEM [mnuMenuItem] AL MENU [mnuPrincipal]
                    mnuPrincipal.Items.Add(mnuMenuItem)
                    'LLAMANDO AL MÉTODO RECURSIVO ENCARGADO DE GENERAR EL ÁRBOL DEL MENÚ
                    AddMenuItem(mnuMenuItem, dtMenuItems)
                End If
            Next
        End If
    End Sub

    Private Sub AddMenuItem(ByRef mnuMenuItem As MenuItem, ByVal dtMenuItems As Data.DataTable)
        'RECORRIENDO CADA ELEMENTO DEL DataTable PARA PODER DETERMINAR CUÁLES
        'SON ELEMENTOS HIJOS DEL MenuItem DADO PASADO COMO PARÁMETRO ByRef
        For Each drMenuItem As Data.DataRow In dtMenuItems.Rows
            If drMenuItem("PadreId").ToString.Equals(mnuMenuItem.Value) AndAlso _
            Not drMenuItem("MenuId").Equals(drMenuItem("PadreId")) Then
                Dim mnuNewMenuItem As New MenuItem
                mnuNewMenuItem.Value = drMenuItem("MenuId").ToString
                mnuNewMenuItem.Text = drMenuItem("Descripcion").ToString
                mnuNewMenuItem.ImageUrl = drMenuItem("Icono").ToString
                mnuNewMenuItem.NavigateUrl = drMenuItem("Url").ToString
                'AGREGANDO EL NUEVO MenuItem AL MenuItem QUE VIENE DE UN NIVEL SUPERIOR
                mnuMenuItem.ChildItems.Add(mnuNewMenuItem)
                'LLAMADA RECURSIVA PARA VER SI EL NUEVO MenuItem AÚN TIENE ELEMENTOS HIJOS
                AddMenuItem(mnuMenuItem, dtMenuItems)
            End If
        Next
    End Sub
End Class
Por último, la definición de la base de datos, tabla, procedimiento almacenado para cargar los datos:
Código:
create database DBApp;
go
USE DBApp
GO
create table Menu
(
MenuId int identity(1,1) PRIMARY KEY,
Descripcion varchar(20) NOT NULL,
PadreId int NOT NULL,
Posicion int NOT NULL,
Icono varchar(100),
Habilitado bit NOT NULL,
Url varchar(100),
FechaCreacion datetime,
UsuarioCreacion char(10),
FechaModificacion datetime,
UsuarioModificacion char(10)
)
go
CREATE PROCEDURE dbo.ObtenerOpcionesMenu
AS
	SET NOCOUNT ON
	   SELECT MenuId, Descripcion, Posicion, PadreId, Icono, Habilitado, Url
	   FROM dbo.Menu
        WHERE Habilitado = 1

	SET NOCOUNT OFF
go
[*] Con estos datos, solamente habrá niveles superiores, sin subniveles:
Código:
MenuId | Descripcion | PadreId | Posicion |        Icono        | Habilitado | Url | FechaCreacion | UsuarioCreacion | FechaModificacion | UsuarioModificacion
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   1   | INICIO      |    1    |     1    | images/earth2.gif   | True       |  #  | NULL          | NULL            | NULL              | NULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   2   | DATOS       |    2    |     1    | images/lock.gif     | True       |  #  | NULL          | NULL            | NULL              | NULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   3   | CLIENTES    |    3    |     1    | images/man.gif      | True       |  #  | NULL          | NULL            | NULL              | NULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   4   | MANUAL      |    4    |     1    | images/help2.gif    | True       |  #  | NULL          | NULL            | NULL              | NULL
[*] Con estos datos, el registro CLIENTES será subnivel de DATOS, y MANUAL como tiene el campo Habilitado a false no aparecerá (tal como se define en la consulta del procedimiento):
Código:
MenuId | Descripcion | PadreId | Posicion |        Icono        | Habilitado | Url | FechaCreacion | UsuarioCreacion | FechaModificacion | UsuarioModificacion
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   1   | INICIO      |    1    |     1    | images/earth2.gif   | True       |  #  | NULL          | NULL            | NULL              | NULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   2   | DATOS       |    2    |     1    | images/lock.gif     | True       |  #  | NULL          | NULL            | NULL              | NULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   3   | CLIENTES    |    2    |     1    | images/man.gif      | True       |  #  | NULL          | NULL            | NULL              | NULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------
   4   | MANUAL      |    4    |     1    | images/help2.gif    | False      |  #  | NULL          | NULL            | NULL              | NULL

Tras construir la base de datos con la tabla necesaria e insertar varias filas, lo he probado.

Pasa una cosa, cuánto menos curiosa (igual porque no sé su causa):
- si en la tabla Menu solo hay registros que sean elementos de nivel superior (que no sean hijos ó subniveles de otro nivel ó subnivel), entonces funciona.
- pero a nada que configure uno de los registros como subnivel de otro, entonces me sale una ventana del WebDev.WebServer.exe con este mensaje:

Cita:
WebDev.WebServer.exe ha detectado un problema y debe cerrarse. Sentimos los inconvenientes ocasionados.
Si está en pleno proceso, puede perderse la información que esté trabajando
¿¿Alguien me podría indicar por qué ocurre esto??
¿Hay algún fallo en el código a la hora de construir los submenús ó elmentos hijo, ó en las propiedades de diseño del control Menu empleado?
__________________
Saludos,

zacktagnan.
=================================================