Mi sitio InicioRegistrarseEntrada
Inicio » 2012 » Noviembre » 30 » Mensajes de Foro con Algoritmo Recursivo vb.NET
8:49 PM
Mensajes de Foro con Algoritmo Recursivo vb.NET

Un ejemplo practico con el cual haras uso de tablas y algoritmos recursivos para recuperar tu información. Esto es aplicable a foros aunque tambien puedes usarlo para información que requiera vinculación padre-hijo en tablas de bd, además de la creacion y uso de controles en tiempo de ejecución.

La idea general parte de una tabla recursiva de la siguiente forma:

taMensajesForo(

CodigoTemaForo char(3)
CodigoMensajeForo char(3)
tituloMensajeForo char(50)
descripcionMensajeForo char(1000)
CodigoMensajeForoPadre char(15)
usuariocrea char(20)

)
Tenemos esta tabla donde registramos los mensajes para un tema especifico (para estos casos el idMensajePadre quedaria vacio o nulo).. luego en algun momento respondemos a un determinado mensaje entonces el campo idMensajePadre almacenará el codigo del mensaje al cual respondemos.
La información se almacena sin mayor dificultad el problema es cuando queremos recuperar la información,

Ok aqui vamos.. lo primero es generar dos procedimientos almacenados uno para recuperar los mensajes que no tengan hijos y el otro para obtener mensajes hijos de un mensaje padre

1er procedimiento:

CREATE PROCEDURE spObtenerMensajesTema
(
@CodigoTemaForo CHAR(15)
)
AS
SELECT
CodigoTemaForo,
CodigoMensajeForo,
CodigoMensajeForoPadre,
TituloMensajeForo,
DescripcionMensajeForo,
usuariocrea

FROM
taMensajesForo

WHERE
CodigoTemaForo = @CodigoTemaForo and
CodigomensajeForoPadre = '000000000000000' // Usamos este codigo para decir que no tiene hijos

2do procedimiento

CREATE PROCEDURE spObtenerMensajesHijo
(
@CodigoMensajeForoPadre CHAR(15)
)
AS
SELECT
CodigoTemaForo,
CodigoMensajeForo,
CodigoMensajeForoPadre,
TituloMensajeForo,
DescripcionMensajeForo,
usuariocrea

FROM
saelse.taMensajeForo

WHERE
CodigomensajeForoPadre = @CodigoMensajeForoPadre// obtenemos todos los mensajes de un mensaje padre

OK ,... hasta aqui hemos generados los 2 procedimientos almacenados que luego invocaremos desde .net. Ahora nos toca generar nuestro webform para obtener la data

 

Web form mensaje.aspx

Creamos el form mensajel archivo .aspx y su codebehind .aspx.vb



En el archivo aspx Agregamos 1 datagrid que hara enlace con la data

<asp:datagrid id="dgMensajesTema" runat="server" Width="100%" OnItemCommand="panel_click" AutoGenerateColumns="False"
GridLines="Horizontal">
<Columns>
... aqui agregaremos las columnas
</Columns>
</asp:datagrid>

A este datagrid lo llamamos dgMensajesTema le dimos el evento panel_click en el evento OnItemCommand y ahora le vamos a agregar las columnas

<asp:BoundColumn DataField="CodigoMensajeForoPadre" Visible="false"></asp:BoundColumn>
<asp:BoundColumn DataField="CodigoTemaForo" Visible="false"></asp:BoundColumn>
<asp:BoundColumn DataField="CodigoMensajeForo" Visible="false"></asp:BoundColumn>

Tres campos enlazados pero que no los mostraremos, esto nos servira para hacer las consultas a la BD, debes tener en cuenta que codigomensajeforopadre esta en la columna 0, codigotemaforo en la columna 1 y asi sucesivamente... luego agregamos la columna donde mostraremos los mensajes sin padre (un template column) y un panel donde agregaremos sus hijos

<asp:TemplateColumn HeaderText="Mensaje">
<ItemTemplate>// insertamos una tabla solo para q la info salga ordenada
<table width="100%" border="0" cellSpacing="0" cellPadding="0" borderColor="gainsboro">
<tr>
<td colspan="2" height="20px" >
<asp:ImageButton id="Imagebutton2" commandname="panel" runat="server" ImageUrl="../imagenes/plus.gif"></asp:ImageButton>
Mensaje creado por <%# DataBinder.Eval(Container.DataItem,"usuarioCrea") %> :
<asp:HyperLink id="hlMensajes" runat="server" tooltip= '<%# DataBinder.Eval(Container.DataItem,"DescripcionMensajeForo") %>' NavigateUrl='enlace a un webform detalle' text = '<%# DataBinder.Eval(Container.DataItem,"TituloMensajeForo") %>' >
</asp:HyperLink>
</td>
<td bgcolor="#e6eefb" height="20px" class="normal" align="right">
<asp:Label id="Label5" runat="server" CssClass="normal">
<%# DataBinder.Eval(Container.DataItem,"FechaCreacion") %>
</asp:Label>
</td>
</tr>
</table>// fin de la tabla.

// aqui insertamos el panel para mostrar y ocultar los mensajes hijo

<asp:Panel id="Panel2" runat="server" Width="100%" Visible="false">
<TABLE id="Table3" cellSpacing="0" cellPadding="0" width="100%" border="0">
<TR vAlign="top">
<TD id="PanelIzquierdo" vAlign="top" width="60%" bgColor="#f9f8f7" rowSpan="2" runat="server"></TD>
</TR>
</TABLE>
</asp:Panel>

</ItemTemplate>
</asp:TemplateColumn>

Bueno doy la aclaración de que en un primer momento "PanelIzquierdo" no va a aparecer (es obvio verdad?) y tan solo se mostraran los mensajes padre tal como muestra la figura:


Y solo haciendo click en la cruz al lado de cada mensaje obtendremos todos los mensajes hijo

Ahora nos vamos al codigo behind osea al mensaje.aspx.vb
En el PanelIzquierdo mostraremos la info de los hijos insertando dinamicamente controls , para nuestro caso hyperlinks e imagenes entonces

Primero declaramos nuestras variables

Dim codigoTemaForo As String
 
Nuestros controles para insertarlos dinamicamente
 
Dim WithEvents hlResponder As HyperLink
Dim WithEvents hlnodo As HyperLink
Dim WithEvents hlTituloAs HyperLink
Dim iDinamico As System.Web.UI.WebControls.Image
 
en el Load
 
Private Sub Page_Load(......)
   CodigoTemaForo="001200500000002"
  'Si la pagina es accesada por primera vez
  If Page.IsPostBack  = false then
         'La idea es cargar los mensajes que no tengan hijos,
        dgMensajesTema.DataSource = f_Obtenermensajetema(CodigoTemaForo)
        dgMensajesTema.DataBind()
  End If
End Sub
 
Luego vamos declarando todas las funciones definidas y las que nos serviran 
Las dos funciones que devuelven datasets y llaman a los procedimientos almacenados que creamos
 Function f_Obtenermensajetema(ByVal paramCodigoTemaForo As String) As DataSet
       
' Crea instancia de conexion y el objeto Command
        Dim
cnxDBINTRANET As New SqlConnection(ConfigurationSettings.AppSettings("connectionString"))
        Dim
sqlObtenerMensajeTemaForo As New SqlDataAdapter("spObtenerMensajesTema", cnxDBINTRANET)
       
' Marcamos el Command como un SPROC
       
sqlObtenerMensajeTemaForo.SelectCommand.CommandType = CommandType.StoredProcedure
      
 ' Agregamos los parametros al procedimiento
        Dim
parametercodigoTema As New SqlParameter("@CodigoTemaForo", SqlDbType.Char, 15)
       
parametercodigoTema.Value = paramCodigoTemaForo
      
 sqlObtenerMensajeTemaForo.SelectCommand.Parameters.Add(parametercodigoTema)
     
  Dim dsObtenerMensajeTema As New DataSet
       
' Creamos y llenamos el DataSet
       
sqlObtenerMensajeTemaForo.Fill(dsObtenerMensajeTema)
        Return
dsObtenerMensajeTema
    End Function
 
 Function f_ObtenermensajesHijo(ByVal paramcodigoMensajePadre As String) As DataSet
       
' Crea instancia de conexion y el objeto Command
        Dim
cnxDBINTRANET As New SqlConnection(ConfigurationSettings.AppSettings("connectionString"))
        Dim
sqlObtenerMensajeTemaForo As New SqlDataAdapter("spObtenerMensajesHijo", cnxDBINTRANET)
       
' Marcamos el Command como un SPROC
       
sqlObtenerMensajeTemaForo.SelectCommand.CommandType = CommandType.StoredProcedure
      
 ' Agregamos los parametros al procedimiento
        Dim
parametercodigoTema As New SqlParameter("@CodigoMensajePadre", SqlDbType.Char, 15)
       
parametercodigoTema.Value = paramcodigoMensajePadre
      
 sqlObtenerMensajeTemaForo.SelectCommand.Parameters.Add(parametercodigoTema)
     
  Dim dsObtenerMensajeTema As New DataSet
       
' Creamos y llenamos el DataSet
       
sqlObtenerMensajeTemaForo.Fill(dsObtenerMensajeTema)
        Return
dsObtenerMensajeTema
    End Function

Luego el evento que se lanza al hacer clic sobre la cruz (Imagebutton2), es aqui donde llamamos al algoritmo recursivo
 
 Public Sub panel_click(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
        If
e.CommandName = "panel" Then 'ocultamos o mostramos el panel de resultados
            Dim
temp1 As Panel = CType(e.Item.FindControl("Panel2"), Panel)
           
temp1.Visible = Not (temp1.Visible)
                  'recuerdan los campos ocultos? pues bien es aqui donde los usamos
                  'en esta caso al codigoMensajeForoPadre
           
obtenerhijos(e.Item.Cells(2).Text, 1, temp1)
            Dim
temp2 As ImageButton = CType(e.Item.FindControl("Imagebutton2"), ImageButton)
            If
temp1.Visible Then 'cambiamos el icono del imagebutton
             
  temp2.ImageUrl = "../imagenes/minus.gif"
            Else
               
temp2.ImageUrl = "../imagenes/plus.gif"
            End If
        End If
    End Sub

Ahora definimos a nuestro obtenerhijos. Este metodo hace uso de llamadas recursivas como veremos

 
Sub obtenerhijos(ByVal codigomensaje As String, ByVal nivel As Integer, ByVal panel As Panel)
  Dim
dr_ As DataSet = f_ObtenerMensajesHijo(codigomensaje)
  Dim
dr As DataRow
  For Each
dr In dr_.Tables(0).Rows
    Dim mensajePadre As String
    Dim
TituloPadre As String
    Dim
DescripcionPadre As String
    Dim
usuarioPadre As String
    Dim
fechaPadre As String
    Dim
nroarchivos As Integer
  
    mensajePadre = CType(dr("CodigomensajeForo"), String)
   
TituloPadre = CType(dr("TituloMensajeForo"), String)
   
DescripcionPadre = CType(dr("DescripcionMensajeForo"), String)
   
usuarioPadre = CType(dr("usuarioCrea"), String)
   
fechaPadre = CType(dr("Fechacreacion"), DateTime).ToShortDateString()
 
    'ubicamos al panel donde insertaremos los mensajes hijo
    Dim parent As Control = panel.FindControl("PanelIzquierdo")
    hlResponder = New HyperLink
   
hlTitulo = New HyperLink
   
hlnodo = New HyperLink
 
    With hlTitulo
      .CssClass =
"normal"
      .Visible = True
      .Text =
"Creado por " + usuarioPadre + " : " + TituloPadre + ". Fecha: " + fechaPadre
      .NavigateUrl =
Request.ApplicationPath + " pagina de detalle de mensaje.."
   
End With

   With hlResponder
      .ImageUrl =
"../imagenes/1x1.gif"
      .Width = New
System.Web.UI.WebControls.Unit(10)
      .Height = New
System.Web.UI.WebControls.Unit(30)
   End With

   With hlnodo
      .ImageUrl = "../imagenes/node.gif"
   End With

   'aqui insertamos imagenes en blanco para dar la apariencia de arbol a nuestros mensajes
   obtenerEspacio(nivel, panel)
   'aqui agregamos los controles
   parent.Controls.Add(hlnodo)
   parent.Controls.Add(hlTitulo)
   parent.Controls.Add(hlResponder)
   parent.Controls.Add(New LiteralControl("<" & "br" & ">"))
   'aqui la llamada recursiva
   If mensajePadre <> "" Then
     
obtenerhijos(mensajePadre, nivel + 1, panel)
   End If
Next dr
End Sub
 
Aqui el módulo para los espacios en blanco esto para dar la apariencia de  arbol
 
Sub obtenerEspacio(ByVal entero As Integer, ByVal panel As Panel)
        While
entero > 0
           
iDinamico = New System.Web.UI.WebControls.Image
            With
iDinamico
                .Visible = True
                .ImageUrl =
"../imagenes/1x1.gif"
                .Width = New
System.Web.UI.WebControls.Unit(30)
            End With
            Dim
parent As Control = panel.FindControl("Panelizquierdo")
           
parent.Controls.Add(iDinamico)
            entero = entero - 1

        End While
    End Sub
  
 

Y listo!! eso es todo, ya arriba hay una imagen con las muestra del ejemplo ejecutandose

Aclaraciones .

Tenemos una tabla con SQL Server 2000 llamada taMensajes con las características que mencione anteriormente. La conexión a la BD es almacenada en el web.config asi:

<appSettings>
<add key="ConnectionString" value="server=localhost;database=dbPrueba;uid=sa;pwd=sa;" />
</appSettings>


Dim cnxDBINTRANET as New SqlConnection(ConfigurationSettings.AppSettings("connectionString")) Dim

Reeemplazariamos el valor de ConfigurationSettings.AppSettings("connectionString") por "server=localhost;data......"
y eso es todo.

Vi un ejemplo con algoritmos recursivos pero lo hacia la BD.. eso tambien sirve aunque cuando el numero de llamadas crece el gestor puede colapsar.

Vistas: 469 | Agregado por: miket | Valoración: 0.0/0
Total de comentarios: 0
Solamente los usuarios registrados pueden agregar comentarios.
[ Registrarse | Entrada ]
Martes, 11.26.2024, 5:48 AM
Menú del sitio
Formulario de entrada
Búsqueda
Archivo de registros
Estadística

Total en línea: 1
Invitados: 1
Usuarios: 0
Calendario
«  Noviembre 2012  »
LuMaMiJuViSaDo
   1234
567891011
12131415161718
19202122232425
2627282930
 






Copyright nientiendo © 2024 Miguel A. Vallejo Duran