Hello,
I´m not a professional in vb.net, but i try to make a tool for my colleague and me. I got a XMLTreeView on my form and i load a XML-File in it. Now, I want to set each node in the XMLTreeView another icon, but it must set by the XML-File.

This is my XML-File :

<?xml version="1.0" encoding="utf-8" ?> <Nodes> <Node Text="Programme" Icon="BlaBlub.ico"> <Node Text="Test" Icon="C:\MyProgramm\Icons\icon2.ico"> <Programm Path="C:\Program Files (x86)\Microsoft Visual" & _
        "Studio\2017\Enterprise\Common7\IDE\devenv.exe">Visual Studio</Programm> <Programm Path="C:\Program Files (x86)\Microsoft" & _
      "Office\root\Office16\EXCEL.EXE">Excel</Programm> </Node> <Node Text="andere" Icon="C:\MyProgramm\Icons\23.ico"> <Programm Path="C:\Program Files (x86)\Microsoft Visual" & _
        "Studio\VB98\VB6.EXE">VB.NET</Programm> </Node> <Node Text="Test1" Icon="Huhu.ico"> <Programm>bla</Programm> <Programm>blup</Programm> </Node> </Node> </Nodes>

This is my vb.net code :

Option Explicit On
Option Strict On
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Runtime.InteropServices
Imports System.Net.NetworkInformation
Imports System.IO
Imports System.Text
Imports System.Diagnostics
Imports System.ComponentModel
Imports System.Drawing
Imports System.Management
Imports Microsoft.Win32
Imports System.Threading
Imports System.Xml
Imports System.Collections.Generic
Imports System.Windows.Forms
Public Class XmlTreeView
    Public Class MyTreeNode
        Inherits TreeNode
        Public Property Path As String
    End Class
   Public Shared Sub LoadFromXml(ByVal FileName As String, ByVal TheTreeView As TreeView)
        Dim xDoc As New XmlDocument
        xDoc.Load(FileName)
        FillTreeView(TheTreeView.Nodes, xDoc.DocumentElement)
    End Sub
    Private Shared Sub FillTreeView(ByVal CurrentNodes As TreeNodeCollection, ByVal xNode As XmlNode)
        For Each xChild As XmlNode In xNode.ChildNodes
            If xChild.Name <> "Programm" Then
                FillTreeView(CurrentNodes.Add(xChild.Name).Nodes, xChild)
            Else
                CurrentNodes.Add(New MyTreeNode With {.Text = xChild.InnerText, .Path = xChild.Attributes("Path").Value})
            End If
        Next
    End Sub
    Sub treeView1_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
        Try
            Dim path = TryCast(TreeView1.SelectedNode, MyTreeNode).Path
            If path IsNot Nothing Then Process.Start(path)
        Catch ex As Exception
            MsgBox("kein Programm gefunden")
        End Try
        Select Case e.Node.Text
            Case "Visual Studio"
                MsgBox("Visual Studio")
                '...
            Case "Excel"
                MsgBox("Excel")
                '...
        End Select
    End Sub
    Private Sub XmlTreeView_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Controls.AddRange(New Control() {TreeView1})
        Me.TreeView1.Nodes.Clear()
        XmlTreeView.LoadFromXml("nodes - kopie.xml", Me.TreeView1)
        'TreeView1.Nodes(0).Expand()
    End Sub
End Class

I created on my form an ImageList too.

How can i set the icon for each node? I think it has to be dynamically. But I don´t know no how to do this... (I don´t want to load all Icons to the ImageList manually)

I hope you can give me some code, please.

Recommended Answers

All 55 Replies

First you should copy the images to an ImageList Click Hereinstance and assign to the TreeView.ImageList property.

If you need to resize the images before embedding them into the ImageList control you may take a look here.

I know, but i don´t know how to copy the images to an ImageList and assign to the TreeView.ImageList property by my code...

If the xml is the following:

<?xml version="1.0" encoding="utf-8" ?>
<Nodes>
  <Node Text="Programme" Icon="C:\Users\Public\Pictures\treeView1.bmp">
    <Node Text="Test" Icon="C:\Users\Public\Pictures\treeView2.bmp">
      <Programm Path="devenv.exe">Visual Studio</Programm>
      <Programm Path="EXCEL.EXE">Excel</Programm>
    </Node>
    <Node Text="andere" Icon="C:\Users\Public\Pictures\treeView2.bmp">
      <Programm Path="VB6.EXE">VB.NET</Programm>
    </Node>
    <Node Text="Test1" Icon="C:\Users\Public\Pictures\treeView1.bmp">
      <Programm>bla</Programm>
      <Programm>blup</Programm>
    </Node>
  </Node>
</Nodes>

and the code maybe this one:

Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml

Dim imgLst As New ImageList
Dim vImgPath(-1) As String, iv As Int32 = 0
Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    imgLst.ImageSize = New Drawing.Size(30, 27)
    LoadXML()
End Sub
Private Sub LoadXML()
    Try
        ' Get Xml's file stream.
        '
        Dim _assembly As [Assembly] = [Assembly].GetExecutingAssembly
        Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")
        Dim _rStream As New IO.StreamReader(_stream)

        ' Load Xml document.
        '
        Dim dom As New XmlDocument()
        dom.Load(_rStream.BaseStream)

        ' Initialize treeView control.
        '
        treeView1.Nodes.Clear()
        treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
        Dim tNode As TreeNode = treeView1.Nodes(0)

        ' Populate the treeView with the dom nodes.
        '
        treeView1.Nodes.Add(dom.DocumentElement.Name)
        AddNode(dom.DocumentElement, tNode)
        If iv Then
            For i = 0 To iv - 1
                imgLst.Images.Add(Image.FromFile(vImgPath(i)))
            Next
            treeView1.ImageList = imgLst
        End If
    Catch xmlEx As XmlException
        MessageBox.Show(xmlEx.Message)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub
Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
    Dim xNode As XmlNode
    Dim tNode As TreeNode
    Dim nodeList As XmlNodeList
    Dim i As Integer
    If inXmlNode.HasChildNodes Then
        nodeList = inXmlNode.ChildNodes
        i = 0
        While i <= nodeList.Count - 1
            xNode = inXmlNode.ChildNodes(i)
            Dim imgIndex As Int32 = -1
            For Each att As XmlAttribute In inXmlNode.Attributes
                If att.Name = "Icon" Then
                    imgIndex = addImage(att.Value)
                End If
            Next
            If imgIndex <> -1 Then
                inTreeNode.ImageIndex = imgIndex
            End If
            inTreeNode.Nodes.Add(New TreeNode(xNode.Name))
            tNode = inTreeNode.Nodes(i)
            AddNode(xNode, tNode)
            i += 1
        End While
    Else
        inTreeNode.Text = (inXmlNode.OuterXml).Trim
    End If
End Sub
Function addImage(path As String) As Int32
    Dim i As Int32 = Array.IndexOf(vImgPath, path)
    If i = -1 Then
        ReDim Preserve vImgPath(iv)
        Me.vImgPath(iv) = path
        i = iv
        iv += 1
    End If
    Return i
End Function

End Class

here is the treeView:
treeView.PNG

Perhaps a better approximation may be this 'simpler' code:

Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml

    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.
            '
            Dim _assembly As [Assembly] = [Assembly].GetExecutingAssembly
            Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")
            Dim _rStream As New IO.StreamReader(_stream)

            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rStream.BaseStream)

            ' Initialize treeView control.
            '
            treeView1.BeginUpdate()
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))

            ' Populate the treeView with the dom nodes.
            '
            AddNode(dom.DocumentElement, treeView1.Nodes(0))
            If iv Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                treeView1.ImageList = imgLst
            End If
            treeView1.EndUpdate()
            treeView1.ExpandAll()
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                inTreeNode.Nodes.Add(tNode)
                AddNode(xNode, tNode)
                i += 1
            End While
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
End Class

treeView2.PNG

I tried both codes.

But, i get always at startup the messagebox with the error "the value should not be 0" (it is my translation in english, because i got a german version) and after this my treeview is empty.

Is it because i changed

Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")

to

Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.nodes-kopie.xml")

?

ok, if i copy your code and create a xml named "XMLFile1.xml" with your xml-code too, it is still the same Errormessage.
But which value is it?

xmlembed1.PNG xmlembed1.PNG xmlembed2.PNG xmlembed4.PNG xmlembed5.PNG

In Visual Studio explorer right click over the application name and add a new element: a xml file. Paste the xml text inside the new xml file. Next, right click (in VS explorer) over the xml file name and select "properties" (I am translating from spanish) and in "Compile actions" set option "embedded file".
Finally change "MyNameSpace.XMLFile1.xml" to your name space and file name.
You may find the 'MyNameSpace' in the application properties, "application" tab, box "root namespace".
Change 'XMLFile1.xml' by the name you have given to the file.

Thank you, it works.

But now i got my next question : If I do it like this, i can only change the code in the XML-File in my application himself via Visual-Studio.
If i changed the code only in the XML-File in my Application-Folder on my hdd, it ignored them and overwrite it by the old file.
Do you know what i mean?

How can I do change it, that my application load at start the XML-File from my hdd?

I am not very sure if I have understood. The xml file can be modified inside or outside VS, but because it's embedded it goes 'inside' the .exe file. This is, if you copy the executable .exe file to another folder you are also copying the xml file because it's inside the executable (=embedded).

Each time you compile in VS, the xml file is embedded into the .exe file.

You may perfectly change the xml file outside VS. But whenever you want to distribute or use the executable you'll have to compile first, that's all.

I compiled it in vs.
then I copy my exe-File in another folder. After this i started the application, it used the XML-File from inside the application and it created the xml-File in the folder. Then i closed the application.
After this i changed the xml-File by another tool.
When I started again my application it takes again the xml-file from inside the exe-file.

It is necessary, that it starts alway the xml-file from my folder. now matter if my application is newer then the XML-File from my folder.

Then copy the xml file to the executable's folder and replace what now is commented by the uncommented:

         ' Get Xml's file stream.

        'Dim _assembly As [Assembly] = [Assembly].GetExecutingAssembly
        ''Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")
        ''Dim _rStream As New IO.StreamReader(_stream)
        '
        Dim vPath() As String = Split(Application.ExecutablePath, "\")
        vPath(vPath.Length - 1) = "XMLFile1.xml"
        Dim filepath As String = Join(vPath, "\")
        Dim _rstream As New FileStream(filepath, FileMode.Open)

I get an error : "BaseStream is not a Member of System.IO.FileStream"

    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.
            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "XMLFile1.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)
            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rStream.BaseStream)

Yes, sorry, you must remove baseStream so the instruction in line #11 will be dom.Load(_rStream)

I pass to you all the code again to be sure you can get it well.

Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml

    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.

            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "XMLFile1.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)

            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rstream)
            _rstream.Close()

            ' Initialize treeView control.
            '
            treeView1.BeginUpdate()
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))

            ' Populate the treeView with the dom nodes.
            '
            AddNode(dom.DocumentElement, treeView1.Nodes(0))
            If iv Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                treeView1.ImageList = imgLst
            End If
            treeView1.EndUpdate()
            treeView1.ExpandAll()
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                inTreeNode.Nodes.Add(tNode)
                AddNode(xNode, tNode)
                i += 1
            End While
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
End Class

Yeah thank you very much. You made my day!!!

You are welcome.

I got one more problem with my XML-File or TreeView :

If I create the xml-file it looks all right.
Edit_XML.png

If I start my program there are more nodes and then I created... Normaly there is only the first Tree named "Nodes" under this, there should be 2 Nodes named "Programme" and "andere". In the Node "Programme" are only "Visual Studio" and "Excel" and in "andere" only "Notepad".
It looks a little bit strange, then my created XML-File...
form_XML.png

I think there is something wrong in "LoadXML"- or "AddNode"-Private Sub?

Option Strict On
Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml

    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.
            'Dim _assembly As [Assembly] = [Assembly].GetExecutingAssembly
            ''Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")
            ''Dim _rStream As New IO.StreamReader(_stream)
            '
            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "XMLFile1.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)
            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rstream) 'dom.Load(_rStream.BaseStream)
            ' Initialize treeView control.
            '
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
            Dim tNode As TreeNode = treeView1.Nodes(0)
            ' Populate the treeView with the dom nodes.
            '
            treeView1.Nodes.Add(dom.DocumentElement.Name)
            AddNode(dom.DocumentElement, tNode)
            If CBool(iv) Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                TreeView1.ImageList = imgLst
            End If
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim xNode As XmlNode
        Dim tNode As TreeNode
        Dim nodeList As XmlNodeList
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                xNode = inXmlNode.ChildNodes(i)
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                If imgIndex <> -1 Then
                    inTreeNode.ImageIndex = imgIndex
                End If
                inTreeNode.Nodes.Add(New TreeNode(xNode.Name))
                tNode = inTreeNode.Nodes(i)
                AddNode(xNode, tNode)
                i += 1
            End While
        Else
            inTreeNode.Text = (inXmlNode.OuterXml).Trim
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
End Class

Yes, get the AddNode() from my last code, because seems to me the AddNode() is not working properly

    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                inTreeNode.Nodes.Add(tNode)
                AddNode(xNode, tNode)
                i += 1
            End While
        End If
    End Sub

2 more Questions :

  1. It creates also a separate node for Node Name and Node Text. But normaly it should only show one node with only the node text...

  2. Bevor I added the code for the Icons/Pictures, I can start the programms by double click on it with my code. Now I get allways the Exception MessageBox, it can´t find the program. But I don´t know why... The path-string in the xml is the same like bevor!?!?

Here is my code with the process.Start and so on :

Option Strict On
Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml
    Public Class MyTreeNode
        Inherits TreeNode
        Public Property Path As String
    End Class
    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.
            'Dim _assembly As [Assembly] = [Assembly].GetExecutingAssembly
            ''Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")
            ''Dim _rStream As New IO.StreamReader(_stream)
            '
            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "XMLFile1.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)
            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rstream) 'dom.Load(_rStream.BaseStream)
            ' Initialize treeView control.
            '
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
            Dim tNode As TreeNode = treeView1.Nodes(0)
            ' Populate the treeView with the dom nodes.
            '
            treeView1.Nodes.Add(dom.DocumentElement.Name)
            AddNode(dom.DocumentElement, tNode)
            If CBool(iv) Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                TreeView1.ImageList = imgLst
            End If
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                inTreeNode.Nodes.Add(tNode)
                AddNode(xNode, tNode)
                i += 1
            End While
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
    Sub treeView1_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
        Try
            Dim path = TryCast(TreeView1.SelectedNode, MyTreeNode).Path
            If path IsNot Nothing Then Process.Start(path)
        Catch ex As Exception
            MsgBox("kein Programm gefunden")
        End Try
        Select Case e.Node.Text
            Case "Visual Studio"
                MsgBox("Visual Studio")
                '...
            Case "Excel"
                MsgBox("Excel")
                '...
            Case "Notepad"
                MsgBox("Notepad")
                '...
        End Select
    End Sub
End Class

2 more Questions :

  1. It creates also a separate node for Node Name and Node Text. But normaly it should only show one node with only the node text...

  2. Bevor I added the code for the Icons/Pictures, I can start the programms by double click on it with my code. Now I get allways the Exception MessageBox, it can´t find the program. But I don´t know why... The path-string in the xml is the same like bevor!?!?

Here is my code with the process.Start and so on :

Option Strict On
Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml
    Public Class MyTreeNode
        Inherits TreeNode
        Public Property Path As String
    End Class
    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.
            'Dim _assembly As [Assembly] = [Assembly].GetExecutingAssembly
            ''Dim _stream As Stream = _assembly.GetManifestResourceStream("MyNameSpace.XMLFile1.xml")
            ''Dim _rStream As New IO.StreamReader(_stream)
            '
            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "XMLFile1.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)
            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rstream) 'dom.Load(_rStream.BaseStream)
            ' Initialize treeView control.
            '
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
            Dim tNode As TreeNode = treeView1.Nodes(0)
            ' Populate the treeView with the dom nodes.
            '
            treeView1.Nodes.Add(dom.DocumentElement.Name)
            AddNode(dom.DocumentElement, tNode)
            If CBool(iv) Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                TreeView1.ImageList = imgLst
            End If
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                inTreeNode.Nodes.Add(tNode)
                AddNode(xNode, tNode)
                i += 1
            End While
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
    Sub treeView1_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
        Try
            Dim path = TryCast(TreeView1.SelectedNode, MyTreeNode).Path
            If path IsNot Nothing Then Process.Start(path)
        Catch ex As Exception
            MsgBox("kein Programm gefunden")
        End Try
        Select Case e.Node.Text
            Case "Visual Studio"
                MsgBox("Visual Studio")
                '...
            Case "Excel"
                MsgBox("Excel")
                '...
            Case "Notepad"
                MsgBox("Notepad")
                '...
        End Select
    End Sub
End Class

1) Perhaps it can't find the executables because you didn' t employ your's xml:

<?xml version="1.0" encoding="utf-8" ?> <Nodes> <Node Text="Programme" Icon="BlaBlub.ico"> <Node Text="Test" Icon="C:\MyProgramm\Icons\icon2.ico"> <Programm Path="C:\Program Files (x86)\Microsoft Visual" & _
        "Studio\2017\Enterprise\Common7\IDE\devenv.exe">Visual Studio</Programm> <Programm Path="C:\Program Files (x86)\Microsoft" & _
      "Office\root\Office16\EXCEL.EXE">Excel</Programm> </Node> <Node Text="andere" Icon="C:\MyProgramm\Icons\23.ico"> <Programm Path="C:\Program Files (x86)\Microsoft Visual" & _
        "Studio\VB98\VB6.EXE">VB.NET</Programm> </Node> <Node Text="Test1" Icon="Huhu.ico"> <Programm>bla</Programm> <Programm>blup</Programm> </Node> </Node> </Nodes>

2) You may use this variation in order to join node and node text:

    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                Dim bIsTxt As Boolean = False
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                    bIsTxt = True
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                If Not bIsTxt Then
                    inTreeNode.Nodes.Add(tNode)
                    AddNode(xNode, tNode)
                Else
                    inTreeNode.Text += " " + tNode.Text
                End If
                i += 1
            End While
        End If
    End Sub

Something more goes wrong now ;-)

1) here is my xml. the path to the executable is in there.

<?xml version="1.0" encoding="UTF-8"?>
<Programme>
  <Feld Icon="Folder.ico">Feld 1<VisualStudio Path="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe" Icon="VS.png">Visual Studio</VisualStudio>
    <Excel Path="C:\Program Files\Microsoft Office 15\root\office15\EXCEL.EXE" Icon="Excel.png">Excel</Excel>
  </Feld>
  <Home Icon="Folder.ico">Home Place<Notepad Path="C:\Program Files\Notepad++\notepad++.exe" Icon="notepad.png">Notepad ++</Notepad>
  </Home>
</Programme>

2) now, it shows name and text together... normaly it would shows only the text. And now it loads the first image for all nodes.
form_XML_1.png

What I get with the variated code:

treeView3.PNG

Yes, you can see for Example at "Programm Visual Studio" <-- "Programm" = node-name ; "Visual Studio" = node-text.

Normaly in TreeViews only node-text is shown.

I don´t know why, but the images for each nodes are allways the same. I tried by the taking the whole path to the icon/png in the xml and i tried it with only the the file too. <- nothing works. It´s allways the "old" folder.ico for all nodes in the treeview.
tree.png

<?xml version="1.0" encoding="UTF-8"?>
<Programme>
  <Feld Icon="Folder.ico">Feld 1<VisualStudio Path="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe" Icon="I:\TestProgramm\eigen Test\xmltest_vb-paradies\xmltest\bin\Debug\VS.png">Visual Studio</VisualStudio>
    <Excel Path="C:\Program Files\Microsoft Office 15\root\office15\EXCEL.EXE" Icon="Excel.png">Excel</Excel>
  </Feld>
  <Home Icon="Folder.ico">Home Place<Notepad Path="C:\Program Files\Notepad++\notepad++.exe" Icon="notepad.png">Notepad ++</Notepad>
  </Home>
</Programme>

I tried also to changes the code, that it shows only the node.text, but it doesn´t work.

And the last problem is, it doesn´t read the "path"-attribute, so i can´t start the programs. the error message is always the exception from try/catch in my sub treeView1_NodeMouseDoubleClick.
Here is my complete code :

Option Strict On
Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml
    Public Class MyTreeNode
        Inherits TreeNode
        Public Property Path As String
    End Class
    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "nodes.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)
            Dim dom As New XmlDocument()
            dom.Load(_rstream) 
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
            Dim tNode As TreeNode = treeView1.Nodes(0)
             treeView1.Nodes.Add(dom.DocumentElement.Name)
            AddNode(dom.DocumentElement, tNode)
            If CBool(iv) Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                TreeView1.ImageList = imgLst
            End If
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim imgIndex As Int32 = -1
                For Each att As XmlAttribute In inXmlNode.Attributes
                    If att.Name = "Icon" Then
                        imgIndex = addImage(att.Value)
                    End If
                Next
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim tNode As New TreeNode(xNode.Name)
                Dim bIsTxt As Boolean = False
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                    bIsTxt = True
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                If Not bIsTxt Then
                    inTreeNode.Nodes.Add(tNode)
                    AddNode(xNode, tNode)
                Else
                    inTreeNode.Text += " " + tNode.Text
                End If
                i += 1
            End While
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
    Sub TreeView1_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
        Try
            Dim path = TryCast(TreeView1.SelectedNode, MyTreeNode).Path
            If path IsNot Nothing Then Process.Start(path)
        Catch ex As Exception
            MsgBox("kein Programm gefunden")
        End Try
        Select Case e.Node.Text
            Case "Visual Studio"
                MsgBox("Visual Studio")
                '...
            Case "Excel"
                MsgBox("Excel")
                '...
            Case "Notepad"
                MsgBox("Notepad")
                '...
        End Select
    End Sub
End Class

Try this:

Imports System.Xml
Imports System.Reflection
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class treeViewLoadXml

    Dim imgLst As New ImageList
    Dim vImgPath(-1) As String, iv As Int32 = 0
    Private Sub treeViewLoadXml_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        imgLst.ImageSize = New Drawing.Size(30, 27)
        LoadXML()
    End Sub
    Private Sub LoadXML()
        Try
            ' Get Xml's file stream.

            Dim vPath() As String = Split(Application.ExecutablePath, "\")
            vPath(vPath.Length - 1) = "XMLFile1.xml"
            Dim filepath As String = Join(vPath, "\")
            Dim _rstream As New FileStream(filepath, FileMode.Open)

            ' Load Xml document.
            '
            Dim dom As New XmlDocument()
            dom.Load(_rstream)
            _rstream.Close()

            ' Initialize treeView control.
            '
            treeView1.BeginUpdate()
            treeView1.Nodes.Clear()
            treeView1.Nodes.Add(New TreeNode(dom.DocumentElement.Name))

            ' Populate the treeView with the dom nodes.
            '
            AddNode(dom.DocumentElement, treeView1.Nodes(0))
            If iv Then
                For i = 0 To iv - 1
                    imgLst.Images.Add(Image.FromFile(vImgPath(i)))
                Next
                treeView1.ImageList = imgLst
            End If
            treeView1.EndUpdate()
            treeView1.ExpandAll()
        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            Dim nodeList As XmlNodeList
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                Dim xNode As XmlNode = inXmlNode.ChildNodes(i)
                Dim imgIndex As Int32 = -1
                If xNode.Attributes IsNot Nothing Then
                    For Each att As XmlAttribute In xNode.Attributes
                        If att.Name = "Icon" Then
                            imgIndex = addImage(att.Value)
                            Exit For
                        End If
                    Next
                End If
                Dim tNode As New TreeNode(xNode.Name)
                Dim bIsTxt As Boolean = False
                If tNode.Text = "#text" Then
                    tNode.Text = xNode.Value
                    bIsTxt = True
                End If
                If imgIndex <> -1 Then
                    tNode.ImageIndex = imgIndex
                End If
                If bIsTxt Then
                    inTreeNode.Text += " " + tNode.Text
                Else
                    inTreeNode.Nodes.Add(tNode)
                    AddNode(xNode, tNode)
                End If
                i += 1
            End While
        End If
    End Sub
    Function addImage(path As String) As Int32
        Dim i As Int32 = Array.IndexOf(vImgPath, path)
        If i = -1 AndAlso IO.File.Exists(path) Then
            ReDim Preserve vImgPath(iv)
            Me.vImgPath(iv) = path
            i = iv
            iv += 1
        End If
        Return i
    End Function
End Class
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.