TreeView: Agregar item (VB 2005)

17/01/2006 - 13:11 por gambini | Informe spam
Saludos a todos. Invoco su ayuda. Tengo una aplicación tipo Windows Explorer.
A la izquierda tengo un TreeView y a la derecha un DataGridView1(dentro de
un Form). Cuando termino de digitar "producto1" en una celda del
DataGridView1, se agrega "producto1" debajo del nodo seleccionado en el
TreeView. El código es el
siguiente:
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellEventArgs) Handles
DataGridView1.CellEndEdit
'***********para agregar nodo (item) al treeview
Dim newNode As TreeNode = New
TreeNode(DataGridView1.CurrentCell.Value)
ExplorerMain.TreeView.SelectedNode.Nodes.Add(newNode)
End Sub
La pregunta es: ¿Cómo hago para que "producto1" se guarde, de modo que
cuando vuelvo a correr la aplicación, "producto1" se visualice en el
TreeView?

Preguntas similare

Leer las respuestas

#1 Jesús Villalobos
17/01/2006 - 17:29 | Informe spam
Entiendo que quieres persistir en disco el contenido del treeview de forma
que al abrir de nuevo la aplicación se muestre en el treeview lo que había
al cerrarla, ¿lo he entendido bien?


"gambini" escribió en el mensaje
news:
Saludos a todos. Invoco su ayuda. Tengo una aplicación tipo Windows
Explorer.
A la izquierda tengo un TreeView y a la derecha un DataGridView1(dentro de
un Form). Cuando termino de digitar "producto1" en una celda del
DataGridView1, se agrega "producto1" debajo del nodo seleccionado en el
TreeView. El código es el
siguiente:
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellEventArgs) Handles
DataGridView1.CellEndEdit
'***********para agregar nodo (item) al treeview
Dim newNode As TreeNode = New
TreeNode(DataGridView1.CurrentCell.Value)
ExplorerMain.TreeView.SelectedNode.Nodes.Add(newNode)
End Sub
La pregunta es: ¿Cómo hago para que "producto1" se guarde, de modo que
cuando vuelvo a correr la aplicación, "producto1" se visualice en el
TreeView?
Respuesta Responder a este mensaje
#2 gambini
18/01/2006 - 15:16 | Informe spam
Jesús, lo has entendido perfectamente. Eso es lo que intento hacer.

"Jesús Villalobos" escribió:

Entiendo que quieres persistir en disco el contenido del treeview de forma
que al abrir de nuevo la aplicación se muestre en el treeview lo que había
al cerrarla, ¿lo he entendido bien?


"gambini" escribió en el mensaje
news:
> Saludos a todos. Invoco su ayuda. Tengo una aplicación tipo Windows
> Explorer.
> A la izquierda tengo un TreeView y a la derecha un DataGridView1(dentro de
> un Form). Cuando termino de digitar "producto1" en una celda del
> DataGridView1, se agrega "producto1" debajo del nodo seleccionado en el
> TreeView. El código es el
> siguiente:
> Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As
> System.Windows.Forms.DataGridViewCellEventArgs) Handles
> DataGridView1.CellEndEdit
> '***********para agregar nodo (item) al treeview
> Dim newNode As TreeNode = New
> TreeNode(DataGridView1.CurrentCell.Value)
> ExplorerMain.TreeView.SelectedNode.Nodes.Add(newNode)
> End Sub
> La pregunta es: ¿Cómo hago para que "producto1" se guarde, de modo que
> cuando vuelvo a correr la aplicación, "producto1" se visualice en el
> TreeView?



Respuesta Responder a este mensaje
#3 gambini
19/01/2006 - 21:00 | Informe spam
Gracias, Jesús. Tu estrategia funciona muy bien.

"Jesús Villalobos" escribió:

Probablemente hay varias estrategias para hacer eso. Te voy a dar una solución que yo utilizo en un programa, pero te advierto que la cosa tiene su miga y que involucra un par de rutinas recursivas y la serialización.

La cosa está en utilizar unas clases que se sincronicen con los nodos del tree y luego serializar esas clases. Para recuperar los nodos has de deserializar las clases y hacer el proceso inverso. Las clases han de tener una estructura jerárquica y dinámica, como la del propio tree. Además han de estar marcadas como serializables. He aquí las clases:

**************************

<System.Serializable()> Public Class Arbol
Public Nodos() As Nodo
Public Sub AñadirNodo(ByVal n As Nodo)
If Nodos Is Nothing Then
ReDim Nodos(0)
Else
ReDim Preserve Nodos(Nodos.GetLength(0))
End If
Nodos(Nodos.GetUpperBound(0)) = n
End Sub

Public Function Serializar() As Xml.XmlDocument
Tryentar esta linea si la clase no tiene objetos jerarquicamente inferioreadir un nuevo GetType por cada tipo jerarquicamente inferior
Dim arrtipos As Type() = {GetType(Nodo)}
Dim xs As New Xml.Serialization.XmlSerializer(GetType(Arbol), arrtipos)
Dim strdoc As New IO.StringWriter
' Añadir Namespaces personalizados
Dim ns As New System.Xml.Serialization.XmlSerializerNamespaces
ns.Add("demo", "http://www.demo.net")
xs.Serialize(strdoc, Me, ns)
Dim xmdoc As New Xml.XmlDocument
xmdoc.LoadXml(strdoc.ToString)
Return xmdoc
Catch ex As Exception
Throw ex
End Try
End Function

Shared Function Deserializar(ByVal xmldoc As Xml.XmlDocument) As Arbol
Try
Dim arrtipos As Type() = {GetType(Nodo)}
Dim xs As New Xml.Serialization.XmlSerializer(GetType(Arbol), arrtipos)
Dim strdoc As New System.Xml.XmlTextReader(New System.IO.StringReader(xmldoc.OuterXml))
Dim obj As Arbol
obj = CType(xs.Deserialize(strdoc), Arbol)
Return obj
Catch ex As Exception
Throw ex
End Try
End Function

Public Sub ObtenerTree(ByRef tree As TreeView)
'Convierte los nodos del Tree en nodos serializables
If tree.Nodes.Count > 0 Then
For Each tn As TreeNode In tree.Nodes
Dim n As New Nodo
n.Valor = tn.Text
If tn.Nodes.Count > 0 Then
'Llamada a la rutina recursiva!!!
ObtenerNodos(n, tn)
End If
AñadirNodo(n)
Next
End If
End Sub

Private Sub ObtenerNodos(ByVal n As Nodo, ByRef tn As TreeNode)
'Rutina recursiva
For Each subtn As TreeNode In tn.Nodes
Dim subnodo As New Nodo
subnodo.Valor = subtn.Text
If subtn.Nodes.Count > 0 Then
'Aquí lanzamos la recursiva
ObtenerNodos(subnodo, subtn)
End If
n.AñadirNodo(subnodo)
Next
End Sub

Public Sub CargarTree(ByRef tree As TreeView)
'Carga los nodos del arbol en el tree
For i As Integer = 0 To Nodos.GetUpperBound(0)
Dim tn As New TreeNode
tn.Text = Nodos(i).Valor
If Not Nodos(i).Nodos Is Nothing Then
'Llamada a la recursiva
CargarNodos(tn, Nodos(i))
End If
tree.Nodes.Add(tn)
Next
End Sub

Private Sub CargarNodos(ByRef tn As TreeNode, ByVal n As Nodo)
For i As Integer = 0 To n.Nodos.GetUpperBound(0)
Dim subtn As New TreeNode
subtn.Text = n.Nodos(i).Valor
If Not n.Nodos(i).Nodos Is Nothing Then
'Aquí lanzamos la recursiva
CargarNodos(subtn, n.Nodos(i))
End If
tn.Nodes.Add(subtn)
Next
End Sub
End Class
<System.Serializable()> Public Class Nodo
<System.Xml.Serialization.XmlAttribute()> Public Valor As String
Public Nodos() As Nodo
Public Sub AñadirNodo(ByVal n As Nodo)
If Nodos Is Nothing Then
ReDim Nodos(0)
Else
ReDim Preserve Nodos(Nodos.GetLength(0))
End If
Nodos(Nodos.GetUpperBound(0)) = n
End Sub
End Class
****************************************+

Resumiendo: La clase arbol contiene una matriz de objetos nodo, los cuales a su vez también pueden contener nodos. La rutina ObtenerTree lee los nodos del tree y los convierte en nodos serializables, y requiere una llamada recursiva para explorar los posibles subnodos del TreeNode. La rutina CargarTree hace el recorrido a la inversa.

Todo el contenido del árbol se serializa en formato XML mediante la rutina Serializar. El proceso inverso se realiza con la rutina Deserializar, que es Shared ya que crea un objeto Arbol a partir del contenido del XML

Desde el programa es muy fácil gestionar todo. He creado un form con un tree y tres botones. Observa que el tree se le pasa a las rutinas del arbol ByRef.

********************************************
Private Sub btnLlenarTree_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLlenarTree.Click
Dim n As New TreeNode
n.Text = "Nodo Raiz"
n.Nodes.Add("Nodo 1")
n.Nodes.Add("Nodo 2")
n.Nodes(0).Nodes.Add("SubNodo 1 del Nodo 1")
n.Nodes(0).Nodes.Add("SubNodo 2 del Nodo 1")
n.Nodes(1).Nodes.Add("SubNodo 1 del Nodo 2")
Me.TreeView1.Nodes.Add(n)
Me.TreeView1.ExpandAll()
End Sub


Private Sub btnPersistirTree_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPersistirTree.Click
Dim a As New Arbol
a.ObtenerTree(Me.TreeView1)
Dim xm As System.Xml.XmlDocument
xm = a.Serializar()
xm.Save("Arbol.xml")
End Sub

Private Sub btnCargarTree_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCargarTree.Click
Dim xm As New System.Xml.XmlDocument
xm.Load("Arbol.xml")
Dim a As Arbol
a = Arbol.Deserializar(xm)
a.CargarTree(Me.TreeView1)
Me.TreeView1.ExpandAll()
End Sub
**************************************************
El fichero XML "Arbol.xml" que se genera cuando se salva el XMLDocument contiene lo siguiente:
<?xml version="1.0" encoding="utf-16"?>
<Arbol xmlns:demo="http://www.demo.net">
<Nodos>
<Nodo Valor="Nodo Raiz">
<Nodos>
<Nodo Valor="Nodo 1">
<Nodos>
<Nodo Valor="SubNodo 1 del Nodo 1" />
<Nodo Valor="SubNodo 2 del Nodo 1" />
</Nodos>
</Nodo>
<Nodo Valor="Nodo 2">
<Nodos>
<Nodo Valor="SubNodo 1 del Nodo 2" />
</Nodos>
</Nodo>
</Nodos>
</Nodo>
</Nodos>
</Arbol>
******************************************

Puede parecer complicado al principio pero en realidad es muy fácil, estudiatelo un poco y mírate en la ayuda los objetos XMLSerializer y los atributos para obtener más información.


Jesús Villalobos
Responsable de desarrollo
Consultoría Certia







"gambini" escribió en el mensaje news:
> Jesús, lo has entendido perfectamente. Eso es lo que intento hacer.
>
> "Jesús Villalobos" escribió:
>
>> Entiendo que quieres persistir en disco el contenido del treeview de forma
>> que al abrir de nuevo la aplicación se muestre en el treeview lo que había
>> al cerrarla, ¿lo he entendido bien?
>>
>>
>> "gambini" escribió en el mensaje
>> news:
>> > Saludos a todos. Invoco su ayuda. Tengo una aplicación tipo Windows
>> > Explorer.
>> > A la izquierda tengo un TreeView y a la derecha un DataGridView1(dentro de
>> > un Form). Cuando termino de digitar "producto1" en una celda del
>> > DataGridView1, se agrega "producto1" debajo del nodo seleccionado en el
>> > TreeView. El código es el
>> > siguiente:
>> > Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As
>> > System.Windows.Forms.DataGridViewCellEventArgs) Handles
>> > DataGridView1.CellEndEdit
>> > '***********para agregar nodo (item) al treeview
>> > Dim newNode As TreeNode = New
>> > TreeNode(DataGridView1.CurrentCell.Value)
>> > ExplorerMain.TreeView.SelectedNode.Nodes.Add(newNode)
>> > End Sub
>> > La pregunta es: ¿Cómo hago para que "producto1" se guarde, de modo que
>> > cuando vuelvo a correr la aplicación, "producto1" se visualice en el
>> > TreeView?
>>
>>
>>
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida