ListBox unselect items - vb.net

Want to unselect items on condition. I noticed that when do setselected then i get error on enxt loop because index was changed after first loop, therefore i decided to refresh and make everytime loop again but after one item is unselected i have invinitive loop for second one. How to accomplish that properly? Listbox is binded to datasource.
sss:
For i As Integer = 0 To ListBox1.SelectedItems.Count - 1
Dim variationswert1 As DataRowView = ListBox1.SelectedItems(i)
Dim name As String = ListBox1.GetItemText(variationswert1)
if name = "TR8" Then
ListBox1.SetSelected(i, False)
ListBox1.Refresh()
GoTo sss
End If
Next
EDIT: (for further discussion):
For i = 0 To ListBox1.Items.Count - 1
If ListBox1.SelectedItems.Contains(ListBox1.Items(i)) Then
MsgBox(ListBox1.GetItemText(ListBox1.Items(i)))
MsgBox(ListBox1.SelectedValue.ToString)
ListBox1.SetSelected(i, False)
End If
Next
ListBox1.Refresh()

Your problem is that you are iterating through the Selected Items, but since you are going to change that array, any loop you will run will eventually fail :
For Each will fail because you will modify the collection
For i = 0 to ... will fail because you will remove an item and therfore end in an OutOfRangeException (or something like that)
The idea would be to :
Run through all your items :
If the item is selected and the item text is "TR8", unselect this item
And here would be the code :
Dim FoundItem As Object 'Or Whatever class the items are
For i = 0 to ListBox1.Items.Count - 1
If ListBox1.SelectedItems.Contains(ListBox1.Items(i)) AndAlso _
ListBox1.GetItemText(ListBox1.Item(i)) = "TR8" Then
FoundItem = ListBox1.Items(i)
ListBox1.SetSelected(i, False)
MsgBox(FoundItem.ToString())
End If
Next
ListBox1.Refresh()

Is looping all thi items, not onlys the selected, viable?
sss:
For i As Integer = 0 To ListBox1.Items.Count - 1
If ListBox1.SelectedItems.Contains(ListBox1.Items(i)) Then
Continue For
End If
Dim variationswert1 As DataRowView = ListBox1.Items(i)
Dim name As String = ListBox1.GetItemText(variationswert1)
if name = "TR8" Then
ListBox1.SetSelected(i, False)
ListBox1.Refresh()
GoTo sss
End If
Next
EDIT:
Using for each and leaving the rest the same:
For Each item In ListBox1.Items
If Not ListBox1.SelectedItems.Contains(item) Then
Continue For
End If
Dim variationswert1 As DataRowView = item
Dim name As String = ListBox1.GetItemText(variationswert1)
If name = "TR8" Then
ListBox1.SetSelected(ListBox1.Items.IndexOf(item), False)
ListBox1.Refresh()
GoTo sss
End If
Next
Simplifing it, I may have not understood it, but it seems that you want to unslect all the listbox items that their text is "TR8"
For Each item In ListBox1.Items
If ListBox1.SelectedItems.Contains(item) And ListBox1.GetItemText(item) = "TR8" Then
ListBox1.SetSelected(ListBox1.Items.IndexOf(item), False)
ListBox1.Refresh()
End If
Next
EDIT 2:
So without for each and
For i As Integer = 0 To ListBox1.Items.Count - 1
If ListBox1.SelectedItems.Contains(ListBox.Items(i)) And ListBox1.GetItemText(ListBox.Items(i)) = "TR8" Then
ListBox1.SetSelected(i, False)
ListBox1.Refresh()
End If
Next

Related

getting System.InvalidOperationException: Listbox DataSource VB.net

This is the error I am getting
System.InvalidOperationException: 'List that this enumerator is bound to has been modified. An enumerator can only be used if the list does not change.'
I have a Listbox that is databound The list of items are stored days table the saved value is stored in a record table. The List is a Comma Separated List E.G: 1,2,3,4,5
Would equate to Items with values of 1 -5 being selected on load.
This is the save Routine which Works perfectly
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.Leave
Dim listboxItems As New List(Of String)
For Each row As DataRowView In ListBox1.SelectedItems
listboxItems.Add(row("IDNum"))
Next row
selectLoad = True
lblDays.Text = String.Join(",", listboxItems.ToArray())
End Sub
This is Routine Which is Throwing the error.
Private Sub BGWLoadData_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGWLoadData.RunWorkerCompleted
Dim TextBoxStrings() As String = {""}
Try
Dim TempStr() As String = lblDays.Text.Split(",")
ReDim TextBoxStrings(TempStr.Count - 1)
TextBoxStrings = TempStr
Catch ex As Exception
End Try
Dim TextBoxDoubles(TextBoxStrings.Count - 1) As Double
For a As Integer = 0 To TextBoxStrings.Count - 1
Try
TextBoxDoubles(a) = TextBoxStrings(a)
Catch ex As Exception
TextBoxDoubles(a) = 0
End Try
Next
Do While DaysBound = False
Application.DoEvents()
Loop
ListBox1.SelectedItems.Clear()
Dim TempIndex As Integer = 0
For Each row As DataRowView In ListBox1.Items
For a As Integer = 0 To TextBoxDoubles.Count - 1
If row("IDNum") = TextBoxDoubles(a) Then
ListBox1.SetSelected(TempIndex, True)
End If
Next
TempIndex = TempIndex + 1
Next row
End Sub
What am I doing wrong or what can be done to make the code more efficient.
Edit:
Error Occurs at Next Row.
Also telling me I have done something wrong isn't helpful I know something is Wrong because I am getting errors. I am asking for is how to fix this with a code snippet or something.
This Has been Solved by Adding a second arrary
If selectLoad = False Then
' convert CSV of IDNums of selected items in listbox into string array
Dim TextBoxStrings() As String = {""}
Try
Dim TempStr() As String = lblDays.Text.Split(",")
ReDim TextBoxStrings(TempStr.Count - 1)
TextBoxStrings = TempStr
Catch ex As Exception
End Try
' convert string array to double array
Dim TextBoxDoubles(TextBoxStrings.Count - 1) As Double
For a As Integer = 0 To TextBoxStrings.Count - 1
Try
TextBoxDoubles(a) = TextBoxStrings(a)
Catch ex As Exception
TextBoxDoubles(a) = -1
End Try
Next
' load underlying IDNums into temporary array
Dim TempIndex As Integer = 0
Dim TempIDNums(ListBox1.Items.Count - 1) As Integer
For Each row As DataRowView In ListBox1.Items
TempIDNums(TempIndex) = row("IDNum")
TempIndex = TempIndex + 1
Next row
' if any of the underlying IDNums are found in the CSV, select that item in the listbox
ListBox1.SelectedItems.Clear()
For ListItemCounter As Integer = 0 To TempIDNums.Count - 1
For SelectedItemCounter As Integer = 0 To TextBoxDoubles.Count - 1
If TempIDNums(ListItemCounter) = TextBoxDoubles(SelectedItemCounter) Then
ListBox1.SetSelected(ListItemCounter, True)
End If
Next
Next
End If

How can I select something from a listbox

Is there a way to read the string that is in a listbox item, prompt the user to enter the string, and if the user enters it in correctly SELECT the next item until there are no items left to select? I am making this in VB.NET. Help would be greatly appreciated.
You could do something like this:
Dim items = ListBox1.Items.Cast(Of Object)().Select(Function(x) x >= x.ToString).ToList()
If items.Contains(TextBox1.Text) Then
Dim nextIndex = items.IndexOf(TextBox1.Text) + 1
If nextIndex < items.Count Then 'There is next item
Dim nextItem = items(nextIndex).ToString()
'Do something with your nextItem
End If
End If
Basically, you try to get all texts in your ListBox by doing this:
Dim items = ListBox1.Items.Cast(Of Object)().Select(Function(x) x >= x.ToString).ToList()
Then you check if an input string is among the text in your ListBox:
If items.Contains(TextBox1.Text) Then
.
.
.
End If
If it does, you get the index of the next item:
Dim nextIndex = items.IndexOf(TextBox1.Text) + 1
And if the index of the next item is not exceeding the ListBox's number of of elements, you get the item in the next index:
If nextIndex < items.Count Then 'There is next item
Dim nextItem = items(nextIndex).ToString()
'Do something with your nextItem
End If
Your next string is in the nextItem, do something with it.
Or, without populating the whole item but still getting the same result, you could add additional Where LINQ clause (as suggested by Codexer):
Dim item = ListBox1.Items.Cast(Of Object)().Select(Function(x) x >= x.ToString).Where(Function(y) y = TextBox1.Text).FirstOrDefault()
If Not item Is Nothing Then
Dim nextIndex = ListBox1.Items.IndexOf(item) + 1
If nextIndex < ListBox1.Items.Count Then 'There is next item
Dim nextItem = ListBox1.Items(nextIndex)
'Do something with your nextItem
End If
End If

How to search in listview

I am trying to create a Loop that will read through the information on my ListView through the SubItem to find the text that matches the text in my Textbox whenever I hit the search button and Focuses the listbox onto the matched text. Below is what I have but it keeps telling me that the value of string cannot be converted. I am also pretty sure that my numbers wont loop correctly but I am not really sure how to cause them to loop endlessly till end of statement.
Dim T As String
T = Lines.Text
For r As Integer = 0 to -1
For C As Integer = 0 to -1
If List.Items(r).SubItems(C).Text = Lines.Text Then
List.FocusedItem = T
End If
Next
Next
End Sub
I don't understand your code, but I do understand the question. Below is example code to search all rows and columns of a listview. Search is case insensitive and supports a "find next match" scenario. If a match or partial match is found in any column the row is selected. TextBox1 gets the text to find. FindBtn starts a new search.
Private SrchParameter As String = ""
Private NxtStrtRow As Integer = 0
Private Sub FindBtn_Click(sender As Object, e As EventArgs) Handles FindBtn.Click
If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
SrchParameter = TextBox1.Text
NxtStrtRow = 0
SearchListView()
End If
End Sub
Private Sub ListView1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListView1.KeyDown
If e.KeyCode = Keys.F3 Then
SearchListView()
End If
End Sub
Private Sub SearchListView()
' selects the row containing data matching the text parameter
' sets NxtStrtRow (a form level variable) value for a "find next match" scenario (press F3 key)
If ListView1.Items.Count > 0 Then
If SrchParameter <> "" Then
Dim thisRow As Integer = -1
For x As Integer = NxtStrtRow To ListView1.Items.Count - 1 ' each row
For y As Integer = 0 To ListView1.Columns.Count - 1 ' each column
If InStr(1, ListView1.Items(x).SubItems(y).Text.ToLower, SrchParameter.ToLower) > 0 Then
thisRow = x
NxtStrtRow = x + 1
Exit For
End If
Next
If thisRow > -1 Then Exit For
Next
If thisRow = -1 Then
MsgBox("Not found.")
NxtStrtRow = 0
TextBox1.SelectAll()
TextBox1.Select()
Else
' select the row, ensure its visible and set focus into the listview
ListView1.Items(thisRow).Selected = True
ListView1.Items(thisRow).EnsureVisible()
ListView1.Select()
End If
End If
End If
End Sub
Instead of looping like that through the ListView, try using a For Each instead:
searchstring as String = "test1b"
ListView1.SelectedIndices.Clear()
For Each lvi As ListViewItem In ListView1.Items
For Each lvisub As ListViewItem.ListViewSubItem In lvi.SubItems
If lvisub.Text = searchstring Then
ListView1.SelectedIndices.Add(lvi.Index)
Exit For
End If
Next
Next
ListView1.Focus()
This will select every item which has a text match in a subitem.
Don't put this code in a form load handler, it won't give the focus to the listview and the selected items won't show. Use a Button click handler instead.
This is the easiest way to search in listview and combobox controls in vb net
dim i as integer = cb_name.findstring(tb_name.text) 'findstring will return index
if i = -1 then
msgbox("Not found")
else
msgbox("Item found")
end if

What is causing 'Index was outside the bounds of the array' error?

What is causing 'Index was outside the bounds of the array' error? It can't be my file, defianetly not. Below is my code:
Sub pupiltest()
Dim exitt As String = Console.ReadLine
Do
If IsNumeric(exitt) Then
Exit Do
Else
'error message
End If
Loop
Select Case exitt
Case 1
Case 2
Case 3
End Select
Do
If exitt = 1 Then
pupilmenu()
ElseIf exitt = 3 Then
Exit Do
End If
Loop
Dim score As Integer
Dim word As String
Dim totalscore As Integer = 0
'If DatePart(DateInterval.Weekday, Today) = 5 Then
'Else
' Console.WriteLine("You are only allowed to take the test on Friday unless you missed it")
' pupiltest()
'End If
Dim founditem() As String = Nothing
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
Dim item() As String = line.Split(","c)
founditem = item
Next
Dim stdntfname As String = founditem(3)
Dim stdntsname As String = founditem(4)
Dim stdntyear As String = founditem(5)
Console.Clear()
If founditem IsNot Nothing Then
Do
If stdntyear = founditem(5) And daytoday = founditem(6) Then
Exit Do
ElseIf daytoday <> founditem(6) Then
Console.WriteLine("Sorry you are not allowed to do this test today. Test available on " & item(6).Substring(0, 3) & "/" & item(6).Substring(3, 6) & "/" & item(6).Substring(6, 9))
Threading.Thread.Sleep(2500)
pupiltest()
ElseIf stdntyear <> founditem(5) Then
Console.WriteLine("Year not found, please contact the system analysts")
Threading.Thread.Sleep(2500)
pupiltest()
End If
Loop
End If
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\testtests.csv")
Dim item() As String = line.Split(","c)
Dim mine As String = String.Join(",", item(2), item(3), item(4), item(5), item(6))
For i As Integer = 1 To 10
Console.WriteLine(i.ToString & "." & item(1))
Console.Write("Please enter the word: ")
word = Console.ReadLine
If word = Nothing Or word <> item(0) Then
score += 0
ElseIf word = item(0) Then
score += 2
ElseIf word = mine Then
score += 1
End If
Next
If score > 15 Then
Console.WriteLine("Well done! Your score is" & score & "/20")
ElseIf score > 10 Then
Console.WriteLine("Your score is" & score & "/20")
ElseIf score Then
End If
Next
Using sw As New StreamWriter("F:\Computing\Spelling Bee\stdntscores", True)
sw.Write(stdntfname, stdntsname, stdntyear, score, daytoday, item(7))
Try
Catch ex As Exception
MsgBox("Error accessing designated file")
End Try
End Using
End
End Sub
All help is highly appreciated,
You are constantly replacing the foundItem array when you do founditem = item:
Dim founditem() As String = Nothing
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
Dim item() As String = line.Split(","c)
founditem = item
Next
Also, you are using (=) the assignment operation instead of (==) relational operator, to compare. Refer to this article for help in understanding the difference between the two.
Instead of this: If stdntyear = founditem(5) And daytoday = founditem(6) Then
Use this: If (stdntyear == founditem(5)) And (daytoday == founditem(6)) Then
Now back to your main error. You continue to assign the itemarray to founditem every time you iterate (Which overwrites previous content). At the end of the Iteration you will be left with the last entry in your CSV only... So in other words, founditem will only have 1 element inside of it. If you try to pick out ANYTHING but index 0, it will throw the exception index was outside the bounds of the array
So when you try to do the following later, it throws the exception.
Dim stdntfname As String = founditem(3) 'index 3 does not exist!
To fix it do the following change:
Dim founditem() As String = Nothing
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
'NOTE: Make sure you know exactly how many columns your csv has or whatever column
' you wish to access.
Dim item() As String = line.Split(","c)
founditem(0) = item(0) 'Assign item index 0 to index 0 of founditem...
founditem(1) = item(1)
founditem(2) = item(2)
founditem(3) = item(3)
founditem(4) = item(4)
founditem(5) = item(5)
founditem(6) = item(6)
Next
For more help on how to work with VB.NET Arrays visit this site: http://www.dotnetperls.com/array-vbnet
In your line Dim item() As String = line.Split(","c) there's no guarantee that the correct number of elements exist. It's possible that one of the lines is missing a comma or is a blank trailing line in the document. You might want to add a If item.Length >= 7 and skipping rows that don't have the right number of rows. Also, remember that unlike VB6, arrays in .Net are 0 based not 1 based so make sure that item(6) is the value that you think it is.

Remove items from listview

I have a listview that has multiple entries and each entry has 2 subitems. I am wanting to know how to remove each item in the listview where the subitem(1) equals a certain string.
What would be the best way to do this?
thanks
You can't use a for..each loop to remove items. after you remove the first item, the for...each is broken.
Try this:
Dim pos As Int32
Dim listItem As ListViewItem
For pos = lvw.Items.Count - 1 To 0 Step -1
listItem = lvw.Items(pos)
If listItem.SubItems(1).Text = "testvalue" Then
lvw.Items.Remove(listItem)
End If
Next
Dim listItem As ListViewItem
Dim someName As String
For Each listItem In lvw.Items
If listItem.Text = someName Then
lvw.Items.Remove(listItem)
' If you only want to remove one item with that Text
' you can put an Exit For right here
End If
Next
You can try something like this.
For Each listItem As ListViewItem In ListView1.Items
If listItem.SubItems.Item(1).Text = "SomeName" Then
listItem.Remove()
End If
Next
This is probably the easiest way of removing all the list items.
Do While YOURITEMLIST.Items.Count <> 0
YOURITEMLIST.Items.Remove(YOURITEMLIST.Items(0))
Loop
Dim x As Integer = 0
For Each item6 As ListViewItem In ListView4.Items
Dim f As String = item6.SubItems(1).Text
Dim ind As Integer = item6.Index
For Each item7 As ListViewItem In ListView4.Items
Dim f2 As String = item7.SubItems(1).Text
' MsgBox(f & " 2nd value " & f2)
If (f = f2) Then
x = x + 1
' MsgBox(x & "= time matched" & f)
If (x > 1) Then
MsgBox("delete here")
ListView4.Items.Remove(item6)
End If
End If
Next
x = 0
Next