Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. TreeView Find not working

TreeView Find not working

Scheduled Pinned Locked Moved Visual Basic
data-structures
14 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    treddie
    wrote on last edited by
    #1

    Hi. For the life of me, I cannot get a TreeView Find to work. I have a list of drives, folders and subfolders in my TreeView. I have googled like crazy and either find repeated references to a very simple method, or convoluted methods that seem to apply to something else. Here is a very basic procedure that fails:

    Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

    Me.TreeView1.SelectedNode = Me.TreeView1.Nodes.Find("Client Supplied Files", True)(0)

    End Sub

    I put the Find method in the _AfterSelect event only because I was using that event as a test area to do the find. In other words...If I clicked on any node in the tree, the event would cause the selected node to change to the one specified in the search. But alas, no go. :(( I have to be missing something really simple here. Thank you for any hints!

    L 1 Reply Last reply
    0
    • T treddie

      Hi. For the life of me, I cannot get a TreeView Find to work. I have a list of drives, folders and subfolders in my TreeView. I have googled like crazy and either find repeated references to a very simple method, or convoluted methods that seem to apply to something else. Here is a very basic procedure that fails:

      Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

      Me.TreeView1.SelectedNode = Me.TreeView1.Nodes.Find("Client Supplied Files", True)(0)

      End Sub

      I put the Find method in the _AfterSelect event only because I was using that event as a test area to do the find. In other words...If I clicked on any node in the tree, the event would cause the selected node to change to the one specified in the search. But alas, no go. :(( I have to be missing something really simple here. Thank you for any hints!

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      treddie wrote:

      I have a list of drives, folders and subfolders in my TreeView.

      How did you load them? Something similar to this[^]? In that case not all nodes will be loaded when the control shows, only the nodes that are expanded.

      Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

      T 1 Reply Last reply
      0
      • L Lost User

        treddie wrote:

        I have a list of drives, folders and subfolders in my TreeView.

        How did you load them? Something similar to this[^]? In that case not all nodes will be loaded when the control shows, only the nodes that are expanded.

        Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

        T Offline
        T Offline
        treddie
        wrote on last edited by
        #3

        Hm...I like that solution MUCH better. But in the interests of trying to understand why "my" version won't work (it was an online TreeView demo that I modified slightly), no, it was a fully recursive method. Please see code below:

        Public Class Form1

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Go_cmd.Click
        'Get a list of drives:
        Dim drives As System.Collections.ObjectModel.ReadOnlyCollection(Of IO.DriveInfo) = My.Computer.FileSystem.Drives
        Dim rootDir As String = String.Empty

        'Now loop thru each drive and populate the treeview:
        For i As Integer = 0 To drives.Count - 1
          System.Windows.Forms.Application.DoEvents()
        
          rootDir = drives(i).Name
        
          'Add this drive as a root node:
          TreeView1.Nodes.Add(rootDir)
        
          'Populate this root node:
          PopulateTreeView(rootDir, TreeView1.Nodes(i))
        

        NextDrive:
        Next i

        End Sub

        Private Sub PopulateTreeView(ByVal dir As String, ByVal parentNode As TreeNode)
        Dim folder As String = String.Empty

        Try
          Dim folders() As String = IO.Directory.GetDirectories(dir)
        
          If folders.Length <> 0 Then
            Dim childNode As TreeNode = Nothing
        
            For Each folder In folders
              System.Windows.Forms.Application.DoEvents()
        
              childNode = New TreeNode(folder)
              parentNode.Nodes.Add(childNode)
              PopulateTreeView(folder, childNode)
            Next folder
          End If
        
        Catch ex As System.IO.IOException
          parentNode.Nodes.Add(folder & ": Drive not Ready")
        
        Catch ex As UnauthorizedAccessException
          parentNode.Nodes.Add(folder & ": Access Denied")
        End Try
        

        End Sub

        Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

        If Text <> String.Empty Then
          Dim arr As TreeNode() = TreeView1.Nodes.Find("Client Supplied Files", True)
        
          For i = 0 To arr.Length - 1
            TreeView1.SelectedNode = arr(i)
          Next
        End If
        

        End Sub

        End Class

        L 1 Reply Last reply
        0
        • T treddie

          Hm...I like that solution MUCH better. But in the interests of trying to understand why "my" version won't work (it was an online TreeView demo that I modified slightly), no, it was a fully recursive method. Please see code below:

          Public Class Form1

          Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Go_cmd.Click
          'Get a list of drives:
          Dim drives As System.Collections.ObjectModel.ReadOnlyCollection(Of IO.DriveInfo) = My.Computer.FileSystem.Drives
          Dim rootDir As String = String.Empty

          'Now loop thru each drive and populate the treeview:
          For i As Integer = 0 To drives.Count - 1
            System.Windows.Forms.Application.DoEvents()
          
            rootDir = drives(i).Name
          
            'Add this drive as a root node:
            TreeView1.Nodes.Add(rootDir)
          
            'Populate this root node:
            PopulateTreeView(rootDir, TreeView1.Nodes(i))
          

          NextDrive:
          Next i

          End Sub

          Private Sub PopulateTreeView(ByVal dir As String, ByVal parentNode As TreeNode)
          Dim folder As String = String.Empty

          Try
            Dim folders() As String = IO.Directory.GetDirectories(dir)
          
            If folders.Length <> 0 Then
              Dim childNode As TreeNode = Nothing
          
              For Each folder In folders
                System.Windows.Forms.Application.DoEvents()
          
                childNode = New TreeNode(folder)
                parentNode.Nodes.Add(childNode)
                PopulateTreeView(folder, childNode)
              Next folder
            End If
          
          Catch ex As System.IO.IOException
            parentNode.Nodes.Add(folder & ": Drive not Ready")
          
          Catch ex As UnauthorizedAccessException
            parentNode.Nodes.Add(folder & ": Access Denied")
          End Try
          

          End Sub

          Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

          If Text <> String.Empty Then
            Dim arr As TreeNode() = TreeView1.Nodes.Find("Client Supplied Files", True)
          
            For i = 0 To arr.Length - 1
              TreeView1.SelectedNode = arr(i)
            Next
          End If
          

          End Sub

          End Class

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Unless some other members beats me to it, I'll write a search-implementation tomorrow. Now, :zzz:

          T 1 Reply Last reply
          0
          • L Lost User

            Unless some other members beats me to it, I'll write a search-implementation tomorrow. Now, :zzz:

            T Offline
            T Offline
            treddie
            wrote on last edited by
            #5

            Thank you very much, and no rush.

            J 1 Reply Last reply
            0
            • T treddie

              Thank you very much, and no rush.

              J Offline
              J Offline
              JR212
              wrote on last edited by
              #6

              Here is a code that I made by several examples that I found:

              Public Class cTreeviewFind
              Inherits TreeView
              #Region "Functions"
              Function SearchTree(ByVal root As TreeNode, ByVal text As String) As System.Collections.Generic.List(Of TreeNode)
              Dim nodes As New System.Collections.Generic.List(Of TreeNode)()

                ' case insensitive
                If root.Text.ToUpper().Contains(text.ToUpper()) Then
                  nodes.Add(root)
                End If
              
                For Each node As TreeNode In root.Nodes
                  Dim subNodes As System.Collections.Generic.List(Of TreeNode) = SearchTree(node, text)
                  If (subNodes.Count > 0) Then
                    nodes.AddRange(subNodes)
                  End If
                Next
                Return nodes
              End Function
              
              ''' ''' Zoek in welke node een tekst voorkomt
              ''' 
              ''' 
              ''' 
              ''' 
              ''' 
              ''' 
              ''' 
              Public Function FindNode(ByVal \_nodeCollection As TreeNode, ByVal SearchVal As String, Optional ByVal CaseSensitief As Boolean = False, Optional ByVal CompleteValue As Boolean = False, Optional ByVal refind As Boolean = False) As TreeNode
                Dim tmpNode As TreeNode = Nothing
                Static bFoundSelectedNode As Boolean
                If refind Then bFoundSelectedNode = False
                If Me.SelectedNode.Equals(Me.Nodes(0)) Then
                  bFoundSelectedNode = True
                End If
                For Each \_c As TreeNode In \_nodeCollection.Nodes
                  If \_c.Equals(Me.SelectedNode) Then
                    bFoundSelectedNode = True
                  End If
                  If bFoundSelectedNode = False Then
                    If \_c.Nodes.Count > 0 Then
                      tmpNode = FindNode(\_c, SearchVal, CaseSensitief, CompleteValue)
                      If bFoundSelectedNode = True AndAlso Not tmpNode Is Nothing Then
                        Return tmpNode
                      End If
                    End If
                  Else
                    If CaseSensitief Then
                      If CompleteValue Then
                        If \_c.Text = SearchVal AndAlso \_c.Equals(Me.SelectedNode) = False Then Return \_c
                        If \_c.Nodes.Count > 0 Then tmpNode = FindNode(\_c, SearchVal, CaseSensitief, CompleteValue)
                        If Not tmpNode Is Nothing Then
                          Return tmpNode
                        End If
                      Else
                        If \_c.Text.IndexOf(SearchVal) >= 0 AndAlso \_c.Equals(Me.SelectedNode) = False Then Return \_c
                        If \_c.Nodes.Count
              
              T 1 Reply Last reply
              0
              • J JR212

                Here is a code that I made by several examples that I found:

                Public Class cTreeviewFind
                Inherits TreeView
                #Region "Functions"
                Function SearchTree(ByVal root As TreeNode, ByVal text As String) As System.Collections.Generic.List(Of TreeNode)
                Dim nodes As New System.Collections.Generic.List(Of TreeNode)()

                  ' case insensitive
                  If root.Text.ToUpper().Contains(text.ToUpper()) Then
                    nodes.Add(root)
                  End If
                
                  For Each node As TreeNode In root.Nodes
                    Dim subNodes As System.Collections.Generic.List(Of TreeNode) = SearchTree(node, text)
                    If (subNodes.Count > 0) Then
                      nodes.AddRange(subNodes)
                    End If
                  Next
                  Return nodes
                End Function
                
                ''' ''' Zoek in welke node een tekst voorkomt
                ''' 
                ''' 
                ''' 
                ''' 
                ''' 
                ''' 
                ''' 
                Public Function FindNode(ByVal \_nodeCollection As TreeNode, ByVal SearchVal As String, Optional ByVal CaseSensitief As Boolean = False, Optional ByVal CompleteValue As Boolean = False, Optional ByVal refind As Boolean = False) As TreeNode
                  Dim tmpNode As TreeNode = Nothing
                  Static bFoundSelectedNode As Boolean
                  If refind Then bFoundSelectedNode = False
                  If Me.SelectedNode.Equals(Me.Nodes(0)) Then
                    bFoundSelectedNode = True
                  End If
                  For Each \_c As TreeNode In \_nodeCollection.Nodes
                    If \_c.Equals(Me.SelectedNode) Then
                      bFoundSelectedNode = True
                    End If
                    If bFoundSelectedNode = False Then
                      If \_c.Nodes.Count > 0 Then
                        tmpNode = FindNode(\_c, SearchVal, CaseSensitief, CompleteValue)
                        If bFoundSelectedNode = True AndAlso Not tmpNode Is Nothing Then
                          Return tmpNode
                        End If
                      End If
                    Else
                      If CaseSensitief Then
                        If CompleteValue Then
                          If \_c.Text = SearchVal AndAlso \_c.Equals(Me.SelectedNode) = False Then Return \_c
                          If \_c.Nodes.Count > 0 Then tmpNode = FindNode(\_c, SearchVal, CaseSensitief, CompleteValue)
                          If Not tmpNode Is Nothing Then
                            Return tmpNode
                          End If
                        Else
                          If \_c.Text.IndexOf(SearchVal) >= 0 AndAlso \_c.Equals(Me.SelectedNode) = False Then Return \_c
                          If \_c.Nodes.Count
                
                T Offline
                T Offline
                treddie
                wrote on last edited by
                #7

                FINALLY! One that actually works! :). Now the big $30,000 question is, why doesn't the method that MS and so many others suggest NOT work? Me.TreeView1.SelectedNode = Me.TreeView1.Nodes.Find("Client Supplied Files", True)

                L 1 Reply Last reply
                0
                • T treddie

                  FINALLY! One that actually works! :). Now the big $30,000 question is, why doesn't the method that MS and so many others suggest NOT work? Me.TreeView1.SelectedNode = Me.TreeView1.Nodes.Find("Client Supplied Files", True)

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  treddie wrote:

                  Now the big $30,000 question is, why doesn't the method that MS and so many others suggest NOT work?

                  Here's a free answer to an expensive question; due to the difference between the nodes' key and it's label. The "find" method works on keys[^] (the name of the node), not on the text being displayed. If you only pass a single string when creating a node, it will not have a name. Try the example below and play a bith with it.

                  Imports System.Windows.Forms
                  Module Module1
                  Private TreeView1 As New TreeView()
                  Sub Main()
                  Using f As New Form
                  Dim btn As New Button
                  btn.Dock = DockStyle.Top
                  AddHandler btn.Click, Sub(s As Object, e As EventArgs)
                  Dim foundNodes As TreeNode() = TreeView1.Nodes.Find("Node 39", True)
                  If foundNodes.Length > 0 Then
                  TreeView1.SelectedNode = foundNodes(0)
                  TreeView1.Focus()
                  End If
                  End Sub
                  TreeView1.Dock = DockStyle.Fill
                  For i As Integer = 0 To 40
                  Dim key As String = String.Format("Node {0}", i)
                  Dim label As String = String.Format("Label {0}", i)
                  TreeView1.Nodes.Add(key, label)
                  Next
                  f.Controls.Add(TreeView1)
                  f.Controls.Add(btn)
                  f.ShowDialog()
                  End Using
                  End Sub
                  End Module

                  Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

                  T 1 Reply Last reply
                  0
                  • L Lost User

                    treddie wrote:

                    Now the big $30,000 question is, why doesn't the method that MS and so many others suggest NOT work?

                    Here's a free answer to an expensive question; due to the difference between the nodes' key and it's label. The "find" method works on keys[^] (the name of the node), not on the text being displayed. If you only pass a single string when creating a node, it will not have a name. Try the example below and play a bith with it.

                    Imports System.Windows.Forms
                    Module Module1
                    Private TreeView1 As New TreeView()
                    Sub Main()
                    Using f As New Form
                    Dim btn As New Button
                    btn.Dock = DockStyle.Top
                    AddHandler btn.Click, Sub(s As Object, e As EventArgs)
                    Dim foundNodes As TreeNode() = TreeView1.Nodes.Find("Node 39", True)
                    If foundNodes.Length > 0 Then
                    TreeView1.SelectedNode = foundNodes(0)
                    TreeView1.Focus()
                    End If
                    End Sub
                    TreeView1.Dock = DockStyle.Fill
                    For i As Integer = 0 To 40
                    Dim key As String = String.Format("Node {0}", i)
                    Dim label As String = String.Format("Label {0}", i)
                    TreeView1.Nodes.Add(key, label)
                    Next
                    f.Controls.Add(TreeView1)
                    f.Controls.Add(btn)
                    f.ShowDialog()
                    End Using
                    End Sub
                    End Module

                    Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

                    T Offline
                    T Offline
                    treddie
                    wrote on last edited by
                    #9

                    Heheh...Your code threw me for a second. It looks like you did a C#-to-vb conversion. :) But I figured it out and made the mods to get it to work in vb.Net. (I'm not a "C" guy). Here is my change to your translation, with a caption added to the button:

                    Imports System.Windows.Forms

                    Module Module1
                    Dim TreeView1 As New TreeView

                    Sub Main()
                    'This demo is a test of how a TreeView search behaves for a node name (key) vs. the TEXT of the node as
                    'seen in the TreeView. Searching for the text will fail. YOU NEED THE NAME (KEY) TO DO THE SEARCH.

                    Using f As New Form
                      Dim btn As New Button
                    
                      btn.Dock = DockStyle.Top
                      btn.Text = "Find ""Label 39"""
                    
                      AddHandler btn.Click, AddressOf BClick
                      TreeView1.Dock = DockStyle.Fill
                    
                      For i As Integer = 0 To 40
                        Dim key As String
                    
                        'Comment-out this line, and the search will fail,
                        'because a node's NAME (its KEY) is NOT its TEXT LABEL!:
                        key = String.Format("Node {0}", i)
                    
                        Dim label As String = String.Format("Label {0}", i)
                        TreeView1.Nodes.Add(key, label)
                      Next i
                    
                      f.Controls.Add(TreeView1)
                      f.Controls.Add(btn)
                      f.ShowDialog()
                    
                    End Using
                    

                    End Sub

                    Private Sub BClick(ByVal s As Object, ByVal e As EventArgs)
                    Dim foundNodes As TreeNode() = TreeView1.Nodes.Find("Node 39", True)
                    If foundNodes.Length > 0 Then
                    TreeView1.SelectedNode = foundNodes(0)
                    TreeView1.Focus()
                    End If

                    End Sub

                    End Module

                    This makes complete sense now...The name/key is NOT the text label. Although it is best to make sure the key = text, so that you don't get confused by the results.

                    L 1 Reply Last reply
                    0
                    • T treddie

                      Heheh...Your code threw me for a second. It looks like you did a C#-to-vb conversion. :) But I figured it out and made the mods to get it to work in vb.Net. (I'm not a "C" guy). Here is my change to your translation, with a caption added to the button:

                      Imports System.Windows.Forms

                      Module Module1
                      Dim TreeView1 As New TreeView

                      Sub Main()
                      'This demo is a test of how a TreeView search behaves for a node name (key) vs. the TEXT of the node as
                      'seen in the TreeView. Searching for the text will fail. YOU NEED THE NAME (KEY) TO DO THE SEARCH.

                      Using f As New Form
                        Dim btn As New Button
                      
                        btn.Dock = DockStyle.Top
                        btn.Text = "Find ""Label 39"""
                      
                        AddHandler btn.Click, AddressOf BClick
                        TreeView1.Dock = DockStyle.Fill
                      
                        For i As Integer = 0 To 40
                          Dim key As String
                      
                          'Comment-out this line, and the search will fail,
                          'because a node's NAME (its KEY) is NOT its TEXT LABEL!:
                          key = String.Format("Node {0}", i)
                      
                          Dim label As String = String.Format("Label {0}", i)
                          TreeView1.Nodes.Add(key, label)
                        Next i
                      
                        f.Controls.Add(TreeView1)
                        f.Controls.Add(btn)
                        f.ShowDialog()
                      
                      End Using
                      

                      End Sub

                      Private Sub BClick(ByVal s As Object, ByVal e As EventArgs)
                      Dim foundNodes As TreeNode() = TreeView1.Nodes.Find("Node 39", True)
                      If foundNodes.Length > 0 Then
                      TreeView1.SelectedNode = foundNodes(0)
                      TreeView1.Focus()
                      End If

                      End Sub

                      End Module

                      This makes complete sense now...The name/key is NOT the text label. Although it is best to make sure the key = text, so that you don't get confused by the results.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      treddie wrote:

                      It looks like you did a C#-to-vb conversion. :)

                      Thanks; no conversion, it was a new console-application in the VS-IDE :)

                      T 1 Reply Last reply
                      0
                      • L Lost User

                        treddie wrote:

                        It looks like you did a C#-to-vb conversion. :)

                        Thanks; no conversion, it was a new console-application in the VS-IDE :)

                        T Offline
                        T Offline
                        treddie
                        wrote on last edited by
                        #11

                        I'm curious what that app is?

                        L 1 Reply Last reply
                        0
                        • T treddie

                          I'm curious what that app is?

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #12

                          VS-IDE? Visual Studio 2010.

                          T 1 Reply Last reply
                          0
                          • L Lost User

                            VS-IDE? Visual Studio 2010.

                            T Offline
                            T Offline
                            treddie
                            wrote on last edited by
                            #13

                            Hm, I'll check out the console part. Thanks for all your help, Eddy!

                            L 1 Reply Last reply
                            0
                            • T treddie

                              Hm, I'll check out the console part. Thanks for all your help, Eddy!

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #14

                              treddie wrote:

                              Thanks for all your help, Eddy!

                              My pleasure, glad I could help a bit :)

                              Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups