Ver Mensaje Individual
  #1 (permalink)  
Antiguo 11/06/2008, 09:05
mankel
 
Fecha de Ingreso: marzo-2007
Ubicación: Celayork
Mensajes: 38
Antigüedad: 17 años, 11 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