Delete from ListBox items in a Loop - vb.net

Each Item information get from a file which specified with the name of that item. Even though the selected items will be deleted properly in the listbox but the file of next item will be deleted. I don't know if problem is for Index or anyother part
SourceDir = "c:\"
For Each itemIndex In listHouse.SelectedIndices()
itemIndex = listHouse.SelectedIndices(0)
listHouse.Items.RemoveAt(itemIndex)
MsgBox(listHouse.Items.Item(itemIndex).Text & "R.txt")
File.Delete(SourceDir & listHouse.Items.Item(itemIndex).Text & "R.txt")
Next

You cannot add or remove items from a collection while inside a For/Each loop.
Each time you RemoveAt(n), you change the make-up of the collection you are looping. If you remove item #4, item 5 moves up to its slot. Then after Next, your code will be looking at position 5, and be looking at what was originally #6 - item 5 would be skipped entirely. To prevent this every-other one bug/issue, an exception is thrown when using a For/Each.
Secondly, your File.Delete code is trying to reference the item you just removed!
To iterate a collection and remove some/all items one by one, loop backwards using an indexer. This removes from the end of the collection so nothing can "move up". Like this:
' loop backwards using For n
For n as Integer = listHouse.SelectedIndices.Count -1 to 0 Step-1
itemIndex = listHouse.SelectedIndices(n)
MsgBox(listHouse.Items.Item(n).Text & "R.txt")
File.Delete(SourceDir & listHouse.Items.Item(n).Text & "R.txt")
' also remove the thing AFTER you have used it to delete
listHouse.Items.RemoveAt(n)
Next
If you tried to use a forward For n loop with this sort of action, you'd get the every-other one issue.

Related

Specify column index of selected data in ItemBox to retrieve when iterating through selected items

Basically have an ItemBox with three columns in an Access form. I want to get specific columns when I iterate though the selected items, but I am having difficulty doing so.
Function GetSelectedValues(famList As Variant) As Collection
Dim famListColl As New Collection
' Loop through all of the selected surveys
For Each fam In famList.ItemsSelected
Debug.Print (fam) ' prints the index number of the selected item
Debug.Print (famList.ItemData(fam)) ' this prints out the last columns value for the selected item
famListColl.Add famList.ItemData(fam)
Next
Set GetSelectedValues = famListColl
End Function
If I try to do the following I get an Run-time error '424': Object required error:
Debug.Print(fam.Column(1))
Debug.Print(famList.ItemData(fam).Column(1))
This somewhat works, but only displays the values of the first selected item indefinitely (it doesn't iterate):
Debug.Print(famList.Column(1))
So I need to combine the two somehow, but struggling to figure that much.
Thanks for the help!
Stumbled across this post that helped me sort it out. I doubt I would have figured it out otherwise. Looks like this:
Debug.Print (famList.Column(2, fam))
So the entire solution for me is the following:
Function GetSelectedValues(famList As Variant) As Collection
Dim famListColl As New Collection
' Loop through all of the selected surveys
For Each fam In famList.ItemsSelected
famListColl.Add famList.Column(1, fam)
famListColl.Add famList.Column(2, fam)
Next
Set GetSelectedValues = famListColl
End Function

Find Item.index after using Items.find

How do you look up the index of a contact item that was set using the items.find method? After finding the item, I want to be able to move to the next item, but my code sends me to the first item in the collection. A condensed version of my plan is below...
dim ColItms as items
dim CI as contactItem
Dim CIindex as integer
set CI= ColItms.find("[CompanyName] = ""IBM""")
CIindex = CI.???? ''''' This shows what I'm wanting to do, but don't know how
' now advance to next item in collection
set ci = ColItms.item(CIindex +1) ' i think this would work if I could find CIindex
set ci = ColItms.GetNext ' this fails as it returns the 1st item in the collection
Right now all that seems to work is to loop through each item in the collection to see if it matches the found contact,
Items have no intrinsic index, only an entry id.
To find the next match, use Items.FindNext.

How to remove selected items from a listbox

This is for a VB.NET 4.5 project in VS2015 Community.
I am trying to remove certain selected items from a listbox, but only if the selected item meets a condition. I've found plenty of examples on how to remove selected items. But nothing that works with a condition nested in the loop going through the selected items (at least, I can't get the examples to work with what I'm trying to do...)
Here's my code:
Dim somecondition As Boolean = True
Dim folder As String
For i As Integer = 0 To lstBoxFoldersBackingUp.SelectedItems.Count - 1
If somecondition = True Then
folder = lstBoxFoldersBackingUp.SelectedItems.Item(i)
Console.WriteLine("folder: " & folder)
lstBoxFoldersBackingUp.SelectedItems.Remove(lstBoxFoldersBackingUp.SelectedItems.Item(i))
End If
Next
The console output correctly shows the text for the current iteration's item, but I can't get the Remove() to work. As the code is now, I get the console output, but the listbox doesn't change.
Removing items changes the index position of the items. Lots of ways around this, but from your code, try iterating backwards to avoid that problem. You should also remove the item from the Items collection, not the SelectedItems collection:
For i As Integer = lstBoxFoldersBackingUp.SelectedItems.Count - 1 To 0 Step -1
If somecondition = True Then
folder = lstBoxFoldersBackingUp.SelectedItems.Item(i)
Console.WriteLine("folder: " & folder)
lstBoxFoldersBackingUp.Items.Remove(lstBoxFoldersBackingUp.SelectedItems(i))
End If
Next
You can simply use this in order to remove a selected item from the listbox
ListBox1.Items.Remove(ListBox1.SelectedItem)
I hope this was helpful.
This will not work:
ListBox1.Items.Remove(ListBox1.SelectedItem)
You need to define exactly which items will be deleted, so the next works fine for me:
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
However it removes one line every time it is called.

Save and Load dynamically generated checkedlistbox items

I'm pretty new to VB, so bear with me. On form load, a list of values is pulled from a database, and the values are used to generate a list of checkedlistbox items.
A user will select which checkboxes they want, and then click save, at which point the checked items are stored to a system.collections.arraylist type user setting.
I am able to save the values of the checkboxes to the user settings, but I'm trying to load the saved settings the next time the application is opened, but I'm unsure how to do this. The only way I've been able to do it only gets the checked items, which isn't what I want.
Here's what I'm using to save the items:
Dim list As New ArrayList
For i As Integer = 0 To CheckedListBox1.Items.Count - 1
list.Add(CheckedListBox1.Items(i))
i = i + 1
Next
My.Settings.selectedlistbox = list
My.Settings.Save()
And this is what I've currently got to load the settings, which isn't working at all:
Dim counter As Integer
counter = 0
While counter <= My.Settings.selectedlistbox.Count - 1
CheckedListBox1.SetItemChecked(counter, list(counter))
counter = counter + 1
End While
On a related note, I'm calling the above code prior to the code where the database connection is opened, so I'm thinking this may be a problem too, since I think the checkboxes won't be able to be accessed until they're actually in the application. I tried placing the code after where the checkedlistbox is loaded, but that didn't work either.
Assume that My.Settings.Useropts is a StringCollection, to skip the ArrayList:
' CLEAR OUT OLD SELECTIONS so they do not accumulate
My.Settings.Useropts.Clear
' save items checked
For i As Integer = 0 To CheckedListBox1.CheckedIitems.Count - 1
My.Settings.Useropts.Add(CheckedListBox1.CheckedItems(i))
Next
My.Settings.Save()
Or iterate the checkedindicies collection:
For i As Integer = 0 To CheckedListBox1.CheckedIndicies.Count - 1
My.Settings.Useropts.Add(CheckedListBox1.Items(CheckedIndicies(i))
Next
My.Settings.Save()
' reload from settings
Dim ndx As Integer
For Each s as string in My.Settings.Useropts
ndx = CheckedListBox1.Items.indexOf(s) ' find this string in the list
' if NDX is -1 then the item does not exist;
If ndx <> -1 then
' set the check for the related INDEX, if found:
CheckedListBox1.SetItemChecked(ndx, True)
Else
CheckedListBox1.SetItemChecked(ndx, False)
End If
Next
If there arent default items in the collection you may need to initialize it on FormLoad. The text for the CheckedList box cant change or items wont be found.
Since the Items collection can store Objects, you could devise a Class of {Name, Key} where key uniquely identifies each item, which Name might change as needed. Store the Keys, then find them in the CLB to set that Item's checkstate as above
Fixed typo in SetItemChecked(n, --> `SetItemChecked(ndx,
Added warning about clearing old settings, annotated the restore loop

VB.NET - Loop skipping Items in ListBox

I have a listbox with directories (not local, it is over a network) listed in it.
I am trying to loop through that listbox and remove any empty directories.
However, I noticed that it just skips some empty directories.. I found that if I ran the loop 3 - 5 times it will get them all, but that isn't very efficient.
My Loop:
Dim i As Integer
i = 0
While i < ListBox1.Items.Count
If IO.Directory.GetFiles(ListBox1.Items.Item(i), "*.*").Length = 0 Then
ListBox1.Items.RemoveAt(i)
End If
i = i + 1
End While
So I was just wondering if there is a more efficient way to check the contents of the directory or another way i could achieve this without having to run the loop multiple times.
ListBox1.Items.Count is getting reevaluated every time, making your loop get shorter as time goes on missing some items. A quick solution could be just mark which items you want to remove as you loop.
Dim toRemove As New List(Of ListBoxItem)
For Each item as ListBoxItem in ListBox1.Items
If IO.Directory.GetFiles(item, "*.*").Length = 0 Then
toRemove.Add(item)
End If
Next
For Each item as ListBoxItem in toRemove
ListBox1.Items.Remove(item)
Next
(there is probably a better way, but that's a quick solution off the top of my head)