sábado, 25 de abril de 2020

Mostrar una cadena de texto con formato JSON en un TreeView

En esta entrada Vamos ver como mostrar una cadena de texto con formato JSON en un Treeview.
Antes de Nada, para serializar y deserializar un archivo JSON  en Visual Basic.net utilizaremos la librería de Newtonsoft, la descargamos en nuestro equipo desde su página web y luego en el explorador de soluciones vamos a Referencias y con el botón derecho del ratón pulsamos Administrar paquetes NuGet.

Instalar Dll NewtonSoft para JSON

Esto nos abre una pantalla donde aparece la referencia de NewtonSoft.JSON.

Instalar dll NewtonSoft para JSON

Hecho esto añadimos estas líneas al comienzo de nuestra aplicación.

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

También podemos añadir esta para poder serializar desde visual Basic.

Imports System.Runtime.Serialization.Json

Estas tres funciones copian la cadena con formato JSON en un archivo y luego lo leen con ayuda de la Dll y lo cargan en un  control TreeView.
La función GeneraJSON(fileReader)  se explicó aquí 


Imports System.Text
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

Private Structure Nodo
        Public Nombre As String
        Public Mandatory As String
        Public SoloLectura As String
    End Structure
Dim antiguooutput As String

Public JSONDeserializado As classJSON = New classJSON

'LEE UN ARCHIVO DE TEXTO CON FORMATO JSON AL PULSAR UN BOTÓN DEL FORMULARIO
Private Sub BtnCargarJSON_Click(sender As Object, e As EventArgs) Handles BtnCargarJSON.Click

        If BtnCargarJSON.Text = "Cancelar" Then
            Close()
        Else
            Try
                'creamos el objeto que contendrá el JSON deserializado
                Dim folderBrowserDialog1 As New FolderBrowserDialog
                Dim MachacaFile As Boolean = False
                Dim longPath As Integer

                If OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
                    Dim sr As System.IO.StreamReader = New System.IO.StreamReader(OpenFileDialog1.FileName)
                    sr.Close()

                    fileReader = My.Computer.FileSystem.ReadAllText(OpenFileDialog1.FileName)

                    'aqui tiene que detectar si es un JSON valido 
                    '***********************************
                    Using reader = New StreamReader(OpenFileDialog1.FileName)
                       
                            Using jsonReader = New JsonTextReader(reader)
                                Dim root = JToken.Load(jsonReader)  'aqui carga el tag del JSON de lo leido en texto
                                DisplayTreeView(root, Path.GetFileNameWithoutExtension(OpenFileDialog1.FileName))
                              
                            End Using
                     
                    End Using
                    'Aqui mete la cadena de texto con formato JSON en la clase
                    JSONDeserializado.cadenaJSON = fileReader
                   
                   
                        'Aqui graba un JSON correcto
                        fileReader = GeneraJSON(fileReader)
                        ' Create or overwrite the file.
                        longPath = Len(OpenFileDialog1.FileName)
                        OpenFileDialog1.FileName = Mid(OpenFileDialog1.FileName, 1, longPath - 5)
                        OpenFileDialog1.FileName = OpenFileDialog1.FileName & ".json"
                        Dim fs As FileStream = File.Create(OpenFileDialog1.FileName)

                        Dim info As Byte() = New UTF8Encoding(True).GetBytes(fileReader)
                        fs.Write(info, 0, info.Length)

                        'Close the files.
                        fs.Close()
                   
                    BtnDescargarJSON.Enabled = True
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message, "ERROR")
            End Try
        End If

    End Sub

'CONVIERTE UNA CADENA DE TEXTO CON FORMATO JSON EN UN TREEVIEW (1ª PARTE de 3)
Public Sub MuestraJSON(ByVal strJSON As String)
      
        'ESTE CODIGO CONVIERTE EL String en stream para no tener que copiarlo en un archivo
        '*******************************************************
        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(strJSON)
        Dim stream As MemoryStream = New MemoryStream(byteArray)
        Dim reader As StreamReader = New StreamReader(stream)
        '****************************************************
        ' ESTE CODIGO LEE EL ARCHIVO  COPIADO Y LO MUESTRA EN PANTALLA
        Dim JsonReader = New JsonTextReader(reader)
        Dim root = JToken.Load(JsonReader)
        DisplayTreeView(root, strJSON)

    End Sub

Public Class classJSON
    'Public quitar As New List(Of classJSON)()
    Private _cadenaJSON As String
    Public Property cadenaJSON As String
        Get
            Return _cadenaJSON
        End Get
        Set(ByVal value As String)
            _cadenaJSON = value
        End Set
    End Property


End Class



 'CONVIERTE UNA CADENA DE TEXTO CON FORMATO JSON EN UN TREEVIEW (2ª PARTE de 3)
    Private Sub DisplayTreeView(ByVal root As JToken, ByVal rootName As String)
        TreeView1.BeginUpdate()

        Try
            TreeView1.Nodes.Clear()
       Dim tNode = TreeView1.Nodes(TreeView1.Nodes.Add(New TreeNode("Raiz")))
            tNode.Tag = root
            AddNode(root, tNode)
            ' TreeView1.ExpandAll()
        Finally
            TreeView1.EndUpdate()
        End Try
    End Sub


 'CONVIERTE UNA CADENA DE TEXTO CON FORMATO JSON EN UN TREEVIEW (3ª PARTE de 3)
    Private Sub AddNode(ByVal token As JToken, ByVal inTreeNode As TreeNode)
        If token Is Nothing Then Return

        If TypeOf token Is JValue Then
            Dim childNode = inTreeNode.Nodes(inTreeNode.Nodes.Add(New TreeNode(token.ToString())))
            childNode.Tag = token

            If SoloLectura(childNode) Then
                childNode.ForeColor = Color.DarkRed
            Else
                childNode.ForeColor = Color.Blue
            End If

        ElseIf TypeOf token Is JObject Then
            Dim obj = CType(token, JObject)

            For Each [property] In obj.Properties()
                Dim childNode = inTreeNode.Nodes(inTreeNode.Nodes.Add(New TreeNode([property].Name)))
                childNode.Tag = [property]
                If SoloLectura(childNode) Then
                    childNode.ForeColor = Color.DarkRed
                Else
                    childNode.ForeColor = Color.Blue
                End If
                AddNode([property].Value, childNode)
                'inTreeNode.Tag = New ControlNode.vNodo
            Next
            'rellena los valores de los arrays
        ElseIf TypeOf token Is JArray Then
            Dim array = CType(token, JArray)
            For i As Integer = 0 To array.Count - 1
                Dim childNode = inTreeNode.Nodes(inTreeNode.Nodes.Add(New TreeNode(i.ToString())))
                childNode.Tag = array(i)

                If SoloLectura(childNode) Then
                    childNode.ForeColor = Color.DarkRed
                Else
                    childNode.ForeColor = Color.Blue
                End If
                AddNode(array(i), childNode)
            Next
        Else
            Debug.WriteLine(String.Format("{0} not implemented", token.Type))
        End If
    End Sub

Funcion auxiliar que pone el nodo de color rojo si detecta que es de sólo lectura (utiliza un datagrid como contenedor de los datos y previamente lo ha rellenado desde una BBDD).

Private Function SoloLectura(ByVal node As Object) As Boolean
        SoloLectura = False
        Dim ValorSoloLectura As Nodo

        'For Each row As DataGridViewRow In dgrContainer.Rows
        For Each row As DataGridViewRow In grdDatosJSON.Rows
            ValorSoloLectura.Nombre = row.Cells(1).Value
            'ValorSoloLectura.Nombre = Convert.ToString(row.Cells(i).Value)
            If node.Text = ValorSoloLectura.Nombre Then
                SoloLectura = True
                Exit For
            End If
        Next
    End Function


No hay comentarios:

Publicar un comentario