Search code examples
vb.netvb.net-2010checklistboxcheckeditems

folderbrowserdialog Check Space


I am rather new to VB and I am trying to figure out how I can do a certain routine. I am writing an archive program that has a checklistbox populated with all the directories on a certain drive. As the user checks on of the directories, it goes into a for loop that grabs the directory size and shows it on the form. But the issue that I am having is that once you start choosing more than 4 or 5 it gets slower and slower since it is reading through all the checkeditems and validating file size with. Is there a method for me to just grab last item checked or unchecked so i can just add/subtract from the current size? This my current code looping through all the checked items. Thank you in advance.

Dim fsize As Long = 0
Private Sub chklstbxWorkspace_SelectedIndexChanged(sender As Object, e As EventArgs) Handles chklstbxWorkspace.SelectedIndexChanged

    Dim entry As Object

    If chklstbxWorkspace.CheckedIndices.Count > 0 Then
        btnStartArchive.Enabled = True
    Else
        btnStartArchive.Enabled = False
    End If
    lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected."


    For Each entry In chklstbxWorkspace.CheckedItems
        fsize += DirectorySize("w:\" & entry.ToString, True)
        lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected.  " & Format(fsize, "###,###,###,###,##0") & " bytes."
    Next
    Application.DoEvents()
End Sub

Solution

  • You could probably use a Dictionary to store previously recorded directories and their sizes so you don't have to calculate the sizes again.

    The Dictionary is a collection which stores a key and a value (with the key being unique - since you're looking at folders this should hold up OK, I think but it is something to be aware of). In this case your Key is the folder name and the Value will be the folder size.

    Assuming I have a Form called Form1 I can declare my Dictionary like so:

    Imports System.Collections.Generic
    
    Public Class Form1
        Dim fileSizesDict As Dictionary(Of String, Long) = New Dictionary(Of String, Long)()
    

    Note the imports of System.Collections.Generic.

    And your SelectedIndexChanged handler could then be something like:

    Private Sub chklstbxWorkspace_SelectedIndexChanged(sender As Object, e As EventArgs) Handles chklstbxWorkspace.SelectedIndexChanged
        Dim fsize As Long = 0
        Dim entry As Object
    
        If chklstbxWorkspace.CheckedIndices.Count > 0 Then
            btnStartArchive.Enabled = True
        Else
            btnStartArchive.Enabled = False
        End If
        lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected."
    
    
        For Each entry In chklstbxWorkspace.CheckedItems
            If fileSizesDict.ContainsKey(entry.ToString()) Then
                fsize += fileSizesDict(entry.ToString())
            Else
                Dim directorySize As Long = directorySize("w:\" & entry.ToString, True)
                fsize += directorySize
    
                fileSizesDict.Add(entry.ToString(), directorySize)
            End If
        Next
    
        lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected.  " & Format(fsize, "###,###,###,###,##0") & " bytes."
    End Sub
    

    Couple of things to note:

    1. The first thing we do is search the Dictionary to see if we have already calculated the size of the folder by using the ContainsKey method
    2. If the folder size has been previously calculated then we just get the contents from the Dictionary
    3. Otherwise, we calculate the size and then store it in the Dictionary for future use via the Add method
    4. I moved lblWorkspaceSize.Text = chklstbxWorkspace.CheckedIndices.Count.ToString & " folders selected. " & Format(fsize, "###,###,###,###,##0") & " bytes." outside the For loop....I am not sure of your specific use case but in this case the Label will just be updated with the final calculation results; chop and change this as needed though :-)

    Caveat: There is a caveat here in this approach in that if someone has added more files to (or removed some files from) a directory which has previously had its size calculated then we won't pick up the size change as it is not recalculated...I am not sure if this will have a significant impact on your use case or not but just something worth noting.