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
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:
ContainsKey
methodAdd
methodlblWorkspaceSize.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.