Home > Blockchain >  Multiple Selections from Listbox to rename Folders
Multiple Selections from Listbox to rename Folders

Time:01-15

Have a vb.net userform with a listbox set to multiselect. This is for personal use. The listbox populates itself when the form loads with all the subfolders, by name only, in a designated folder. I want to append a prefix to each selected folder in the listbox. By default, all folders would have the prefix, let's say X. So, for example, Xfolder1 becomes folder1 if selected and the submit button is pressed (not on listbox change).

Here is my code and pseudocode so far. Getting string errors. Only the first sub, loading the form and populating the list works. Many thanks for any help. Health and safety to all during this pandemic.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For Each folder As String In System.IO.Directory.GetDirectories("D:\TestFolder\")
        ListBox1.Items.Add(Path.GetFileName(folder))
    Next
End Sub

This is ofc pseudocode

Private Sub RenameFolders(sender As Object, e As EventArgs) Handles Button1.Click
    For i = 0 To ListBox1.Items.Count - 1         
        If Prefix Exists Then
            FileIO.FileSystem.RenameDirectory(Prefix & FolderName, FolderName)
        Else
            FileIO.FileSystem.RenameDirectory(FolderName, Prefix & FolderName)
        End If
    Next
End Sub

What is above and lots of research. Issue might be with whether my strings are the full path or just the folder name. Listbox returns folder names, but is that what the code returns? Very confused.

Hi. Sorry for the lack of clarity. Because the listbox is populated on load, it will show the current state of the folders. This could be Xfolder1, folder2, xfolder3 etc. It will be the folder names as they currently exist.

Another way to look at it.

Selecting folders will remove any prefix from all selected when submit is hit. Not selecting folders will add the prefix to all non-selected when submit is hit.

If xfolder1 appears in the listbox and is selected, it becomes folder1. If xfolder1 appears in the listbox and is NOT selected, it remains xfolder1. If folder1 appears in the listbox and it is selected, it remains folder1. If folder1 appears in the listbox but is NOT selected, it changes to xfolder1

I hope that makes more sense?

CodePudding user response:

Assuming that I'm understanding your question properly now, I would suggest that you use the DirectoryInfo class. You can create one for the parent folder and then get an array for the subfolders. You can then bind that array to the ListBox and display the Name property, which is just the folder name, while still having access to the FullName property, which is the full path. It also has an Exists property and a MoveTo method for renaming. Here is how I would do what you're asking for:

Imports System.IO

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim folderPath = Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "Test")
        Dim folder As New DirectoryInfo(folderPath)
        Dim subFolders = folder.GetDirectories()

        With ListBox1
            .DisplayMember = "Name"
            .DataSource = subFolders
        End With
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Const prefix As String = "X"

        For Each selectedSubFolder As DirectoryInfo In ListBox1.SelectedItems
            'This is required to update the Exists property if the folder has been deleted since loading.
            selectedSubFolder.Refresh()

            If selectedSubFolder.Exists Then
                Dim parentFolderPath = selectedSubFolder.Parent.FullName
                Dim folderName = selectedSubFolder.Name

                If folderName.StartsWith(prefix) Then
                    folderName = folderName.Substring(prefix.Length)
                Else
                    folderName = prefix & folderName
                End If

                Dim folderPath = Path.Combine(parentFolderPath, folderName)

                selectedSubFolder.MoveTo(folderPath)
            End If
        Next
    End Sub

End Class

Note that this doesn't update the ListBox as it is. If you want that too, here's how I would do it with the addition of a BindingSource:

Imports System.IO

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim folderPath = Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "Test")
        Dim folder As New DirectoryInfo(folderPath)
        Dim subFolders = folder.GetDirectories()

        BindingSource1.DataSource = subFolders

        With ListBox1
            .DisplayMember = "Name"
            .DataSource = BindingSource1
        End With
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Const prefix As String = "X"

        For Each selectedSubFolder As DirectoryInfo In ListBox1.SelectedItems
            'This is required to update the Exists property if the folder has been deleted since loading.
            selectedSubFolder.Refresh()

            If selectedSubFolder.Exists Then
                Dim parentFolderPath = selectedSubFolder.Parent.FullName
                Dim folderName = selectedSubFolder.Name

                If folderName.StartsWith(prefix) Then
                    folderName = folderName.Substring(prefix.Length)
                Else
                    folderName = prefix & folderName
                End If

                Dim folderPath = Path.Combine(parentFolderPath, folderName)

                selectedSubFolder.MoveTo(folderPath)
            End If
        Next

        BindingSource1.ResetBindings(False)
    End Sub

End Class

Note that this will still not resort the data but I'll leave that to you if you want it. The reason is that you could do a simple sort of the DirectoryInfo array on Name but that will do a straight alphabetic sort, which the ListBox can already do. If you want a logical sort like File Explorer does, where actual numbers in folder names are sorted numerically, then you need to use a Windows APi function too, which is beyond the scope of this question. If you want that, see here for more information.

  • Related