Foros del Web » Programación para mayores de 30 ;) » .NET »

Llenar TreeView más rápido

Estas en el tema de Llenar TreeView más rápido en el foro de .NET en Foros del Web. Hola que tal, espero me puedan echar una mano. Estoy programando en VB .net 2005, y mi problema es que, a la hora de llenar ...
  #1 (permalink)  
Antiguo 11/06/2008, 09:05
 
Fecha de Ingreso: marzo-2007
Ubicación: Celayork
Mensajes: 38
Antigüedad: 17 años, 2 meses
Puntos: 3
Llenar TreeView más rápido

Hola que tal, espero me puedan echar una mano.

Estoy programando en VB .net 2005, y mi problema es que, a la hora de llenar un TreeView tarda demasiado. Intento llenar un arbol con más de 14mil nodos, los cuales tardan aproximadamente en repartirse en todo el arbol entre 10 y 15 minutos. Lo que hago es llenar un DataSet con la información que necesita mi función para llenar el TreeView. La función que agrega los nodos al arbol, es recursiva.

Mi BD está en MySQL, no tengo problemas a la hora de conexión ni nada parecido, es más, mi DataSet lo llena en menos de 1seg., el problema como les comento, es a la hora de llenar el TreeView.

Les dejo mi codigo:

Declaro mi DataSet
Código:
Private dataSetArbol As System.Data.DataSet
Aqui tengo mi evento Load, donde llamo a la funcion que me crea el DataSet, terminando, llamo a la función que me crea los nodos en el TreeView:
Código:
    Private Sub frmDesplegaCta_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        CrearDataSet()
        
            ' Llamar al método por primera vez que llenará el TreeView, este método se llamará luego
            ' a sí mismo recurrentemente.
            CrearNodosDelPadre("0", Nothing)


    End Sub

Esta es mi funcion que crea el DataSet, tengo mi consulta hecha y ahi llamo a la funcion que me llena el DataSet.
Código:
   Private Sub CrearDataSet()
        Dim tablaArbol As DataTable
        Dim orden_ant As Integer = 0
        Dim strQuery As String

        dataSetArbol = New DataSet("DataSetArbol")

        strQuery = "select concat(`ecuenta`.`cuenta`,' - ',`ecuenta`.`nombre`) AS `NombreNodo`, `ecuenta`.`cuenta` AS `Cuenta`, " & _
                    "if(`ecuenta`.`nivel`=1,'0',`ectasoc`.`ctasup`) AS `CuentaSuperior` " & _
                    "from `ecuenta` left join `ectasoc` on(`ecuenta`.`cuenta` = `ectasoc`.`subcta`) order by `cuenta`"
        If Not LlenaDataSet(strQuery, dataSetArbol) Then
            MessageBox.Show("Error al conectar a BD", ":S", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If

    End Sub
Esta funcion llena el DataSet con la query que envío de parametro, así como el DataSet
Código:
    Public Function LlenaDataSet(ByVal sQuery As String, ByRef Ds As DataSet) As Boolean
        Dim Adaptador As New MySqlDataAdapter(sQuery, Conexion.cn)
        Ds.Tables.Clear()
        Adaptador.Fill(Ds, "TablaArbol")
        If Ds.Tables("TablaArbol").Rows.Count > 0 Then
            Return True
        Else
            Return False
        End If
    End Function

Esta es la funcion recursiva, que llena el TreeView
Código:
    Private Sub CrearNodosDelPadre(ByVal indicePadre As Integer, ByVal nodePadre As TreeNode)

        Dim dataViewHijos As DataView

        ' Crear un DataView con los Nodos que dependen del Nodo padre pasado como parámetro.
        dataViewHijos = New DataView(dataSetArbol.Tables("TablaArbol"))

        dataViewHijos.RowFilter = dataSetArbol.Tables("TablaArbol").Columns("CuentaSuperior").ColumnName + " = " + indicePadre.ToString()

        ' Agregar al TreeView los nodos Hijos que se han obtenido en el DataView.
        For Each dataRowCurrent As DataRowView In dataViewHijos

            Dim nuevoNodo As New TreeNode
            nuevoNodo.Text = dataRowCurrent("NombreNodo").ToString().Trim()

            ' si el parámetro nodoPadre es nulo es porque es la primera llamada, son los Nodos
            ' del primer nivel que no dependen de otro nodo.
            If nodePadre Is Nothing Then
                TreeView1.Nodes.Add(nuevoNodo)
            Else
                ' se añade el nuevo nodo al nodo padre.
                nodePadre.Nodes.Add(nuevoNodo)
            End If

            ' Llamada recurrente al mismo método para agregar los Hijos del Nodo recién agregado.
            CrearNodosDelPadre(Int32.Parse(dataRowCurrent("Cuenta").ToString()), nuevoNodo)
        Next dataRowCurrent

    End Sub
Gran parte del código que les presento, lo saque de la página de El Guille, donde tiene un ejemplo de cómo llenar un TreeView, si alguien tiene una mejor forma de llenar un TreeView, adelante, me interesa mucho que esto se haga más rápido.

Gracias
  #2 (permalink)  
Antiguo 16/06/2008, 06:47
 
Fecha de Ingreso: enero-2005
Mensajes: 140
Antigüedad: 19 años, 3 meses
Puntos: 0
Respuesta: Llenar TreeView más rápido

Varias cosas.

Los DataSet son muy pesados y muy lentos en su ejecucción. Intenta utilizar colecciones de objetos en sustitucion(ICollection, IList, ...). El rendimiento se nota y sobretodo en fuentes de datos grandes.

Las funciones recursivas a su vez, tambien son muy lentas, ya que empiezan a crear una pila de llamadas de las que muchas veces es complicado salir. Intenta utilizar otro tipo de construcciones para crear el arbol.

Utiliza puntos de interrupcion para ver donde tarda mas.

Yo creo que si investigas en estas dos cosas puedes ganar bastante en rendimiento porque 10 0 15 minutos para 14000 registros me parece una burrada. No deberia tardar mas de 10 o 15 segundos(exagerando) en un pc medio decente.
  #3 (permalink)  
Antiguo 16/06/2008, 09:53
 
Fecha de Ingreso: marzo-2007
Ubicación: Celayork
Mensajes: 38
Antigüedad: 17 años, 2 meses
Puntos: 3
Respuesta: Llenar TreeView más rápido

Gracias por la respuesta Jasp22

Donde tarda más mi código en generar ese TreeView, es en esa función recursiva, porque el DataSet se llena rapidamente (no mas de 1 segundo).

Me gustaría saber como podria llenar el TreeView de otra menera, como lo harias tu tomando en cuenta los registros que son (pueden ser mas).

Espero me puedas dar una idea y si pudieras, un ejemplo.

Muchas gracias
  #4 (permalink)  
Antiguo 17/06/2008, 12:27
 
Fecha de Ingreso: marzo-2007
Ubicación: Celayork
Mensajes: 38
Antigüedad: 17 años, 2 meses
Puntos: 3
Respuesta: Llenar TreeView más rápido

No se si se pueda, pero planteo esto:

No es necesario que se carguen todos los nodos de una sola vez, leí por ahí que para casos como este, lo ideal sería, dibujar los nodo padre (raíz) y conforme el usuario vaya navegando dentro del árbol se vayan agregando los nodos. Solo que no tengo ni la mínima idea de como hacerlo, alguien que me pueda orientar con un ejemplo?


Gracias!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:31.