Home > Blockchain >  VB.NET list of folders in ComboBox using FOR loop
VB.NET list of folders in ComboBox using FOR loop

Time:12-07

I am looking for a way to list subfolders in a set folder using FOr loop. I got this for files in folder like:

            For Each File As String In System.IO.Directory.GetFiles("G:\100 Databases\ASSETS\FLAGS\JPG\")
                .Items.Add(System.IO.Path.GetFileNameWithoutExtension(File))
            Next

But how does this would be for folders

            For Each Folder As String In IO.Directory.GetDirectories(ClientsFolder)
                .Items.Add(System.IO.Path.GetDirectoryName(Folder))
            Next

My version just lists the ClientFolder subfolders number of times but not the actual subfolder name.

CodePudding user response:

The Path class just works on Strings. It doesn't know anything about actual files and folders. It just knows the conventions of file system paths. The GetFileName method will simply get everything after the last "\" delimiter, without distinguishing between file and folder paths. That's what you need to use:

.Items.Add(System.IO.Path.GetFileName(Folder))

That said, there are more improvements you can make to that code.

Firstly, you should generally only use a namespace to qualify a type once. If you would need to use the same namespace twice or more, import that namespace instead. You can import a namespace project-wide on the References page of the project properties or you can import it at the file level at the top of the code, e.g.

Imports System.IO

and then:

For Each Folder As String In Directory.GetDirectories(ClientsFolder)
    .Items.Add(Path.GetDirectoryName(Folder))
Next

Next, it's generally preferable to make a single call to AddRange than it is to make multiple calls to Add. If you're adding individual items here and there then that's different but you should call AddRange rather than Add in a loop. It won't really make much, if any, difference in most cases but it's good to create good habits so you won't do the wrong thing when it does matter, e.g.

Dim folders = Directory.GetDirectories(clientsFolder)

For i = 0 To folders.getUpperBound(0)
    folders(i) = Path.GetFileName(i)
Next

.Items.AddRange(folders)

Notice that I have also used a lower-case character to start variable names. You don't have to do that but it's what Microsoft recommends and it's what the bulk of .NET developers do.

Next, it is often preferable to bind a list to a ComboBox rather than add items directly. For a simple list, it doesn't make too much difference, but it may be advantageous here. What you can do it use DirectoryInfo objects instead of simple Strings. You can then display the Name property, which is just the folder name, but still have access to the FullName property, which is the full path, e.g.

Dim clientsFolder = New DirectoryInfo(clientsFolderPath)
Dim subFolders = clientsFolder.GetDirectories()

.DisplayMember = NameOf(DirectoryInfo.Name)
.ValueMember = NameOf(DirectoryInfo.FullName)
.DataSource = subFolders

When the user selects a folder name, you can then get its full path from the SelectedValue property of the ComboBox.

If you're doing this for files rather than folders then there is a FileInfo class that has the same properties, but it doesn't have a property that will remove the file extension. You can throw a bit of LINQ at the problem though, and make your own, e.g.

Dim filePaths = Directory.GetFiles(clientsFolderPath)

.DisplayMember = "NameWithoutExtension"
.ValueMember = "FullPath"
.DataSource = filePaths.Select(Function(s) New With {.FullPath = s, .NameWithoutExtension = Path.GetFileNameWithoutExtension(s)}).ToArray()

More to follow...

  • Related