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.
  • 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