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