Load all children from a FolderItem into a hierarchal ListBox recursively

Maybe someone has a nice recursive function that when passed a folderitem, it iterates through the children and subchildren all the way down and adds each to a hierarchal listbox using the AddRow and AddFolder as required that they’d like to share?

The included Xojo FileBrowser example only adds the children when the node is expanded, which is nice, but I’d like to load everything at once from a background thread. (I understand that this would be VERY time-consuming on a normal drive, but this is for a small external hardware device that only has a very small drive)


I’ve been working on this for a bit and I can get the list of files, but I can’t seem to get them added hierarchally. i.e. How do I add a row to a “Folder” on the ListBox?

FileListBox.AddFolder(f.Name) // Adds a folder with an expand glyph. FileListBox.AddRow(f.Item(1).Name) // This row is not "inside" the folder

Hi Andy,

Take a look at the Indent property of the ListBox.AddRowAt method.

You get the Indent value using the RowDepthAt method when called on the “Folder” row you added, then add + 1 to the Indent value to make the child appear “inside” the folder row you’re adding.

Generally speaking, the logic would look something like the following:

FileListBox.AddFolder(f.Name) Var indent As Int32 = FileListBox.RowDepthAt(FileListBox.LastAddedRowIndex) FileListBox.AddRowAt(FileListBox.LastAddedRowIndex + 1, f.Item(l).Name, indent + 1)

I hope that helps.

Thank you for your reply. That’s helpful, but the new rows don’t appear and disappear when the glyph is clicked.

I think what I didn’t realize is that the AddRow just creates a normal row with a glyph. It doesn’t actually “contain” any children. It’s simply the “illusion” of children when you add the rows with an indent when clicking the glyph and using the “ExpandRow” event.

I’ll be better off to store the files in some sort of hierarchal array (one that kinda matches a folderitem) that has children and so on and then just adding the children from the array so I don’t have to scan the drive each time.

That’s right.

The rows that are visible in the ListBox control are the only ones contained in the control at that time. On each ExpandRow event you need to recreate your child rows (indented).

Likewise when an expanded Folder row is collapse, the child rows are deleted from the ListBox control.

I believe this is by design for efficiency purposes, when the LIstbox is set to Hierarchical mode. Otherwise the ListBox would potentially require holding a huge amount of information for all rows (most of which may not be visible), when the user may only interact with a few items.

The topic has come up a couple of times before here on the forum.

Don’t use folderitems because those are too slow. FileListMBS is much faster and doesn’t show the beachball anymore.

Dave S has an older custom control. MBS plugins for macOS and Einhugur cross platform have a custom control, too.

I’ve written such an example some time ago… Have a look at this example project.

All is based on a class ‘CTreeListedValues’, which basically is a hierarchical list. Once you’ve built your (hierarchical) list, you just assign it to the subclassed Listbox. All the expanding/collapsing logic is handled and your CTreeListedValues instance is updated accordingly. A contextmenu is provided to expand/collapse all or just a branch (states are stored).

Years ago it had an example that iterated through a folder. It seems I have removed that :wink:
However, it shouldn’t be too difficult to write a method, which calls itself recursively and builds the hierarchical list. You’d best do that in a background Thread. Once the Thread has created the list, you can assign it in the Main Thread to the subclassed Listbox.

And just to mention this: I know, the example is a bit out of date. It uses API 1. And for macOS, you’ll need to switch the Build Settings from 32 to 64Bit to be able to run it on macOS Catalina. But then again - it’s just an example project. Have a look at it. If you like the idea of having an universal “hierarchical list”, which you can use to auto-magically show in a hierarchical Listbox - then this example might be of interest to you. Read and understand how it’s been done (in pure Xojo code, no Plugins), and modify it in a more up-to-date way for yourself.