none
Showing folders/files in a TreeView to be used in tool to select files/folders to backup RRS feed

  • Question

  • Hi

    I am trying to be able to show a provided path (and its contents - files and folders) in a TreeView which will be used in a tool to allow selection of files/folders to copy/backup

    I have tried several different projects/methods found with google and being playing with a great tutorial by IronRazer on DIC (http://www.dreamincode.net/forums/topic/400525-treeview-drive-folder-and-file-explorer/)

    This works well as it also shows correct icons which looks nicer than some other solutions I tried

    I have amended the code to show check boxes and so that when you click a parent then all children are checked

    BUT with this code it only checks the children if the tree is expanded which is no good for me - I suspect it is how it is written to only populate child nodes when expanded, so until expanded it doesn't see anything to check - which make sense, but for the life of me I cannot see what to change so it will check all children even if NOT expanded

    FRANK: for info in case you read this, I also tried doing it using DevExpress TreeList (preferred) which works okay but more basic test as code I found only adds standard file/folder icon and not the correct icon for filetypes etc

    Hope this make sense?


    Darren Rose

    Wednesday, February 22, 2017 1:28 PM

All replies

  • Not sure what code you are using but it should just be:

        Private Sub TreeView1_AfterCheck(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterCheck
            For Each child As TreeNode In e.Node.Nodes
                child.Checked = e.Node.Checked
            Next
        End Sub

    That changes the child node check state whether the parent is expanded or collapsed.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, February 22, 2017 2:07 PM
    Moderator
  • Yes that is similar to code I am using but it doesn't work for the reason I mentioned above - i.e. in the code I am using (link given above) the children it seems are not populated until the node is expanded and I couldn't work out how to change that behaviour in the tutorial code

    I didn't post code here as the link above clearly shows it - but if you want I will post it all here too

    EDIT : My code for checking the child nodes is slightly different as your example only does one level and not subnodes/children etc

    If e.Action <> TreeViewAction.Unknown Then
               If e.Node.Nodes.Count > 0 Then
                    ' Calls the CheckAllChildNodes method, passing in the current 
                    ' Checked value of the TreeNode whose checked state changed. 
                    CheckAllChildNodes(e.Node, e.Node.Checked)
                End If
            End If
    
      
           Private Sub CheckAllChildNodes(treeNode As TreeNode, nodeChecked As Boolean)
            Dim node As TreeNode
            For Each node In treeNode.Nodes
                node.Checked = nodeChecked
                If node.Nodes.Count > 0 Then
                    CheckAllChildNodes(node, nodeChecked)
                End If
            Next node
        End Sub


    Darren Rose


    • Edited by wingers Wednesday, February 22, 2017 2:37 PM
    Wednesday, February 22, 2017 2:10 PM
  • Without reading the entire article, just scanning it, it looks like there is an AddChildNodes() method.  On the AfterCheck event handler, test the node to see if it has any children, if not, call the AddChildNodes method before attempting to change the check state.

    Give that a try and see how it goes.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, February 22, 2017 2:38 PM
    Moderator
  • BUT with this code it only checks the children if the tree is expanded which is no good for me - I suspect it is how it is written to only populate child nodes when expanded...

    I didn't look but that sounds like it could be made to work.

    If the code is set up such that the children nodes are populated dynamically (which is a good way in my opinion) then you could handle the .AfterExpand event and have it look to the checked value of the parent node.

    The hard part would be dealing with tri-state (so that it shows the indeterminate state for all nodes hierarchically above it).

    FRANK: for info in case you read this, I also tried doing it using DevExpress TreeList (preferred) which works okay but more basic test as code I found only adds standard file/folder icon and not the correct icon for filetypes etc

    I never have fiddled with icons and the like, but that would be a great question to ask Dev. They have a heck of a great support team.


    "One who has no vices also has no virtues..."

    Wednesday, February 22, 2017 2:38 PM
  • Without reading the entire article, just scanning it, it looks like there is an AddChildNodes() method.  On the AfterCheck event handler, test the node to see if it has any children, if not, call the AddChildNodes method before attempting to change the check state.

    Give that a try and see how it goes.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Thanks

    Yes been trying that already actually and not getting anywhere, as it seems the child is temporarily stored as *empty* using this code, so it gets confused and gives errors


    Darren Rose

    Wednesday, February 22, 2017 2:46 PM
  • BUT with this code it only checks the children if the tree is expanded which is no good for me - I suspect it is how it is written to only populate child nodes when expanded...

    I didn't look but that sounds like it could be made to work.

    If the code is set up such that the children nodes are populated dynamically (which is a good way in my opinion) then you could handle the .AfterExpand event and have it look to the checked value of the parent node.

    The hard part would be dealing with tri-state (so that it shows the indeterminate state for all nodes hierarchically above it).

    FRANK: for info in case you read this, I also tried doing it using DevExpress TreeList (preferred) which works okay but more basic test as code I found only adds standard file/folder icon and not the correct icon for filetypes etc

    I never have fiddled with icons and the like, but that would be a great question to ask Dev. They have a heck of a great support team.


    "One who has no vices also has no virtues..."

    I don't want to have to expand them to check them so tried in the AfterCheck rather than AfterExpand but as per reply to Reed it doesn't work

    Not sure I need to worry about tri-state indicators

    Will also contact Dev re second question


    Darren Rose

    Wednesday, February 22, 2017 2:48 PM
  • I don't want to have to expand them to check them so tried in the AfterCheck rather than AfterExpand but as per reply to Reed it doesn't work

    I guess that I misunderstood then, but keep this in mind:

    That's just a visual representation of the user's intent. At some point you need to have knowledge of what the user means (what they've selected) and keep those two things in agreement. ;-)


    "One who has no vices also has no virtues..."

    Wednesday, February 22, 2017 2:52 PM
  • Think perhaps I need to start fresh rather than attempting to amend someone else's tutorial - main reason I did was because it showed correct icons for each file type which was nice

    Will put links below to existing code I have done in case anyone wants to look and advise

    The first one is based on IronRazer tutorial I mentioned - benefits are it shows correct images for files

    http://www.pcassistonline.co.uk/TEST/test_filexplorer2.zip

    second one is a DevExpress project, benefits of this is that checking child works okay already, and tri-state works, as this is automated in DevExpress control - only thing which would improve this version is to use Icon bit from other sample in this one

    http://www.pcassistonline.co.uk/TEST/test_fileexplorer_dev.zip


    Darren Rose

    Wednesday, February 22, 2017 2:54 PM
  • Darren,

    Let me know what Dev comes back with. It has me curious now. ;-)


    "One who has no vices also has no virtues..."

    Wednesday, February 22, 2017 3:01 PM
  • Darren,

    Let me know what Dev comes back with. It has me curious now. ;-)


    "One who has no vices also has no virtues..."

    Will do

    Suspect it must be possible somehow, as for example IronRazer has a great class for getting icon images of files, folders, drives, or registered files - just need to integrate that with the Dev code above

    http://www.dreamincode.net/forums/topic/396055-get-icon-images-of-files-folders-drives-or-registered-files/


    Darren Rose

    Wednesday, February 22, 2017 3:04 PM
  • Darren,

    Let me know what Dev comes back with. It has me curious now. ;-)


    "One who has no vices also has no virtues..."

    Pretty generic answer from Dev

    "If you wish to change images that are shown in TreeList, you can add required images to ImageCollection and set them to required nodes in the TreeList.GetStateImage event handler.
    Alternatively, you can draw the images manually using the TreeList.CustomDrawNodeImages event."


    Darren Rose

    Thursday, February 23, 2017 10:08 AM

  • Pretty generic answer from Dev

    "If you wish to change images that are shown in TreeList, you can add required images to ImageCollection and set them to required nodes in the TreeList.GetStateImage event handler.
    Alternatively, you can draw the images manually using the TreeList.CustomDrawNodeImages event."


    Darren Rose

    Darren,

    What were you wanting then?


    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 12:38 PM
  • What was I wanting from Dev? or what was I wanting to achieve?

    Achieve = get correct icons to show for files / filetypes like it does with the test_filexplorer2.zip sample I linked above - at the moment Dev one just shows a standard file or folder icon for each item, whereas the other sample uses a class for getting icons and showing correct ones e.g. PDF icon for .pdf etc


    Darren Rose

    Thursday, February 23, 2017 12:44 PM
  • What was I wanting from Dev? or what was I wanting to achieve?

    Achieve = get correct icons to show for files / filetypes like it does with the test_filexplorer2.zip sample I linked above - at the moment Dev one just shows a standard file or folder icon for each item, whereas the other sample uses a class for getting icons and showing correct ones e.g. PDF icon for .pdf etc


    Darren Rose

    Oh ok - that explains their "generic" reply then:

    They don't get into doing anything like that. They provide great controls and help you set them up and use then, but that's a lot more specific than what they do.


    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 12:49 PM
  • Oh ok - that explains their "generic" reply then:

    They don't get into doing anything like that. They provide great controls and help you set them up and use then, but that's a lot more specific than what they do.


    "One who has no vices also has no virtues..."

    Yes that was as I expected, hence asking on forum instead - but as you suggested in earlier response I asked Dev as well

    Darren Rose

    Thursday, February 23, 2017 12:52 PM

  • Yes that was as I expected, hence asking on forum instead - but as you suggested in earlier response I asked Dev as well

    Darren Rose

    Well it was a thought - I guess I'm still fuzzy on what you need.

    Are you trying to incorporate IR's code into yours? If so then it might be best to wait for him to reply here?


    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 1:18 PM
  • It probably needs someone who uses Dev as well to do this - and not sure if IR does

    To show it in pictures might make more sense - but basically showing correct icons for each file/filetype

    First image is IR solution (test_filexplorer2.zip) above and second is Dev solution

    Was a long shot anyway - will just go without correct images as not end of world, just a thought


    Darren Rose

    Thursday, February 23, 2017 1:26 PM
  • Darren,

    I can't open the .sln in the zip file because of my older version of VS, but if we boil this down is the question then about getting the icon of the file?

    If so then you might want to have a look at this:

    https://msdn.microsoft.com/en-us/library/ms404308(v=vs.110).aspx


    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 1:30 PM
  • Correct

    Yes that seems another way to do it - the IR solution uses his IconHelper class from http://www.dreamincode.net/forums/topic/396055-get-icon-images-of-files-folders-drives-or-registered-files/

    Code below is for the Dev version and works great for showing me the path I want with "default" icons, so I just need to integrate method in msdn site to show correct icons for each item

    The form just contains a Dev TreeList and a textbox

    Imports System.IO
    Imports DevExpress.XtraTreeList.Nodes
    
    Public Class Form1
    
        Dim loadCustomPath As Boolean = True
        Dim customPath As String = "Z:\Backup"
      
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            ' configure treelist
            TreeList1.DataSource = New Object()
            TreeList1.StateImageList = ImageCollection1
            TreeList1.OptionsBehavior.Editable = False
            TreeList1.OptionsBehavior.AllowRecursiveNodeChecking = True
            TreeList1.OptionsView.EnableAppearanceEvenRow = True
            TreeList1.OptionsView.ShowCheckBoxes = True
            TreeList1.OptionsView.ShowIndicator = False
    
            ' done this so then all children get checked correctly with recursive enabled
            TreeList1.ExpandAll()
            TreeList1.CollapseAll()
    
        End Sub
    
        Private Sub TreeList1_VirtualTreeGetChildNodes(ByVal sender As Object, ByVal e As DevExpress.XtraTreeList.VirtualTreeGetChildNodesInfo) Handles TreeList1.VirtualTreeGetChildNodes
            Dim current As Cursor = Cursor.Current
            Cursor.Current = Cursors.WaitCursor
            If loadCustomPath Then
                e.Children = New String() {customPath}
                loadCustomPath = False
            Else
                Try
                    Dim path As String = CStr(e.Node)
                    If Directory.Exists(path) Then
                        Dim dirs() As String = Directory.GetDirectories(path)
                        Dim files() As String = Directory.GetFiles(path)
                        Dim arr(dirs.Length + files.Length - 1) As String
                        dirs.CopyTo(arr, 0)
                        files.CopyTo(arr, dirs.Length)
                        e.Children = arr
                    Else
                        e.Children = New Object() {}
                    End If
                Catch
                    e.Children = New Object() {}
                End Try
            End If
            Cursor.Current = current
        End Sub
    
        Private Sub TreeList1_VirtualTreeGetCellValue(ByVal sender As Object, ByVal e As DevExpress.XtraTreeList.VirtualTreeGetCellValueInfo) Handles TreeList1.VirtualTreeGetCellValue
            Dim di As New DirectoryInfo(CStr(e.Node))
            If e.Column Is colName Then
                If di.FullName = customPath Then
                    e.CellData = di.FullName
                Else
                    e.CellData = di.Name
                End If
            End If
            If e.Column Is colType Then
                If IsDrive(CStr(e.Node)) Then
                    e.CellData = "Drive"
                ElseIf Not IsFile(di) Then
                    e.CellData = "Folder"
                Else
                    e.CellData = "File"
                End If
            End If
            If e.Column Is colSize Then
                If IsFile(di) Then
                    e.CellData = (New FileInfo(CStr(e.Node))).Length
                Else
                    e.CellData = Nothing
                End If
            End If
        End Sub
    
        Private Function IsFile(ByVal info As DirectoryInfo) As Boolean
            Try
                Return (info.Attributes And FileAttributes.Directory) = 0
            Catch
                Return False
            End Try
        End Function
        Private Function IsDrive(ByVal val As String) As Boolean
            Dim drives() As String = Directory.GetLogicalDrives()
            For Each drive As String In drives
                If drive.Equals(val) Then
                    Return True
                End If
            Next drive
            Return False
        End Function
    
        Private Sub treeList1_GetStateImage(ByVal sender As Object, ByVal e As DevExpress.XtraTreeList.GetStateImageEventArgs) Handles TreeList1.GetStateImage
            If e.Node.GetDisplayText("Type") = "Folder" Then
                e.NodeImageIndex = If(e.Node.Expanded, 1, 0)
            ElseIf e.Node.GetDisplayText("Type") = "File" Then
                e.NodeImageIndex = 2
            Else
                e.NodeImageIndex = 3
            End If
        End Sub
    
        Private Sub treeList1_CustomDrawNodeCell(ByVal sender As Object, ByVal e As DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs) Handles TreeList1.CustomDrawNodeCell
            If e.Column Is Me.colSize Then
                If e.Node.GetDisplayText("Type") = "File" Then
                    e.Appearance.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Far
                    Dim size As Int64 = Convert.ToInt64(e.Node.GetValue("Size"))
                    If size >= 1024 Then
                        e.CellText = String.Format("{0:### ### ###} Kb", size \ 1024)
                    Else
                        e.CellText = String.Format("{0} Bytes", size)
                    End If
                Else
                    e.CellText = String.Format("<{0}>", e.Node.GetDisplayText("Type"))
                End If
            End If
    
            If e.Column Is Me.colName Then
                If e.Node.GetDisplayText("Type") = "File" Then
                    e.Appearance.Font = New Font(e.Appearance.Font, FontStyle.Bold)
                End If
            End If
        End Sub
    
        Private Sub TreeList1_AfterCheckNode(sender As Object, e As DevExpress.XtraTreeList.NodeEventArgs) Handles TreeList1.AfterCheckNode
            If e.Node.CheckState = CheckState.Checked Then
                If e.Node.GetValue(1) = "File" Then
                    TextBox1.Text = ("Checked: File - " & FullNameByNode(e.Node, 0))
                End If
    
                If e.Node.GetValue(1) = "Folder" Or e.Node.GetValue(1) = "Drive" Then
                    TextBox1.Text = ("Checked: Folder - " & FullNameByNode(e.Node, 0))
                End If
            End If
            If e.Node.CheckState = CheckState.Unchecked Then
    
                If e.Node.GetValue(1) = "File" Then
                    TextBox1.Text = ("Unchecked: File - " & FullNameByNode(e.Node, 0))
                End If
    
                If e.Node.GetValue(1) = "Folder" Or e.Node.GetValue(1) = "Drive" Then
                    TextBox1.Text = ("Unchecked: Folder - " & FullNameByNode(e.Node, 0))
                End If
            End If
    
        End Sub
    
        Private Function FullNameByNode(ByVal node As TreeListNode, ByVal columnId As Integer) As String
            Dim ret As String = node.GetValue(columnId).ToString()
            Do While node.ParentNode IsNot Nothing
                node = node.ParentNode
                '  ret = node.GetValue(columnId).ToString() & "\" & ret
                ret = String.Concat(node.GetValue(columnId), "\").TrimEnd("\"c) & "\" & ret
            Loop
            Return ret
        End Function
    End Class


    Darren Rose


    • Edited by wingers Thursday, February 23, 2017 1:37 PM
    Thursday, February 23, 2017 1:37 PM
  • Darren,

    You just need to put it all together and I think you'll have it.

    So per file (based on code from https://msdn.microsoft.com/en-us/library/system.drawing.icon.extractassociatedicon(v=vs.110).aspx):

    Private Function _ GetAssociatedIcon(ByVal filePath As String) As Icon Dim retVal As Icon = Nothing Try If Not String.IsNullOrWhiteSpace(filePath) Then Dim fi As New IO.FileInfo(filePath) If fi.Exists Then retVal = Icon.ExtractAssociatedIcon(fi.FullName) End If End If Catch ex As Exception MessageBox.Show(String.Format("An error occurred:{0}{0}{1}", _ vbCrLf, ex.Message), _ "Exception Thrown", _ MessageBoxButtons.OK, _ MessageBoxIcon.Warning) End Try Return retVal End Function


    The fact that you're populating it dynamically lends to my point yesterday:

    At the end of it all, you have to know what the user means. It's not whether or not the nodes beneath are checked - there are no nodes beneath it!


    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 1:55 PM
  • Thanks I will have a try then

    "At the end of it all, you have to know what the user means. It's not whether or not the nodes beneath are checked - there are no nodes beneath it!"

    Seems to work for me? and there are nodes beneath, e.g. if I check top node then all nodes underneath get checked as well 


    Darren Rose

    Thursday, February 23, 2017 2:04 PM
  • ... and there are nodes beneath, e.g. if I check top node then all nodes underneath get checked as well 

    Darren Rose

    That's what I meant exactly.

    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 2:07 PM
  • exactly, so if someone checks Documents then all contents get checked which is correct, as they would be choosing to backup/restore Documents folder so would want all contents

    If they just wanted one file/folder within documents they would check that


    Darren Rose

    Thursday, February 23, 2017 2:11 PM
  • Icon.ExtractAssociatedIcon(fi.FullName) works well for getting icon from file - but it is in icon format and Dev ImageCollection doesn't support that format

    So tried converting to bitmap but then looks horrible and doesn't work - so no further forward yet...


    Darren Rose

    Thursday, February 23, 2017 5:47 PM
  • Icon.ExtractAssociatedIcon(fi.FullName) works well for getting icon from file - but it is in icon format and Dev ImageCollection doesn't support that format

    So tried converting to bitmap but then looks horrible and doesn't work - so no further forward yet...


    Darren Rose

    I'm just  not a graphics guy - it's never been my forte, but I thought that Dev has their own image list version (and that it did support .ico files)?

    Again, I'll defer to them - they know their stuff backward and forward.


    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 5:53 PM
  • Icon.ExtractAssociatedIcon(fi.FullName) works well for getting icon from file - but it is in icon format and Dev ImageCollection doesn't support that format

    So tried converting to bitmap but then looks horrible and doesn't work - so no further forward yet...


    Darren Rose

    I'm just  not a graphics guy - it's never been my forte, but I thought that Dev has their own image list version (and that it did support .ico files)?

    Again, I'll defer to them - they know their stuff backward and forward.


    "One who has no vices also has no virtues..."


    Yes ImageCollection is the Dev version of ImageList and no doesn't support icon unfortunately

    Darren Rose

    Thursday, February 23, 2017 5:54 PM
  • Yes ImageCollection is the Dev version of ImageList and no doesn't support icon unfortunately

    Darren Rose

    I'm not trying to be evasive here - I just plain don't know.

    "One who has no vices also has no virtues..."

    Thursday, February 23, 2017 6:02 PM
  • Yes ImageCollection is the Dev version of ImageList and no doesn't support icon unfortunately


    Darren Rose

    I'm not trying to be evasive here - I just plain don't know.

    "One who has no vices also has no virtues..."

    that's fine - was just answering

    May have got it to work a bit now, but show last file image for all of them rather than each different one - but it is a start!


    Darren Rose

    Thursday, February 23, 2017 6:04 PM