Removing items from a ListBox in VB.net - vb.net

I have two ListBox1 and ListBox2. I have inserted items into a ListBox2 with the following code by selecting ListBox1 item:
da6 = New SqlDataAdapter("select distinct(component_type) from component where component_name='" & ListBox1.SelectedItem() & "'", con)
da6.Fill(ds6, "component")
For Each row As DataRow In ds6.Tables(0).Rows
ListBox2.Items.Add(row.Field(Of String)("component_type"))
Next
But when I reselect another item of ListBox1 then ListBox2 shows preloaded items and now loaded item together.
I want only now loaded item to be displayed in listbox.
I used this code but problem not solved:
For i =0 To ListBox2.items.count - 1
ListBox2.Items.removeAt(i)
Next
OR
listbox2.items.clear() is also not working..
How can I clear all items in the ListBox2?

Use simply:
ListBox2.Items.Clear()
To take your last edit into account: Do that before you add the new items
MSDN: ListBox.ObjectCollection.Clear
Removes all items from the collection.
Note that the problem with your approach is that RemoveAt changes the index of all remaining items.
When you remove an item from the list, the indexes change for
subsequent items in the list. All information about the removed item
is deleted. You can use this method to remove a specific item from the
list by specifying the index of the item to remove from the list. To
specify the item to remove instead of the index to the item, use the
Remove method. To remove all items from the list, use the Clear
method.
If you want to use RemoveAt anyway, you can go backwards, for example with:
a for-loop:
For i As Int32 = ListBox2.Items.Count To 0 Step -1
ListBox2.Items.RemoveAt(i)
Next
or a while
While ListBox2.Items.Count > 0
ListBox2.Items.RemoveAt(ListBox2.Items.Count - 1)
End While
old C# code
for (int i = ListBox2.Items.Count - 1; i >= 0; i--)
ListBox2.Items.RemoveAt(i);
while(ListBox2.Items.Count > 0)
ListBox2.Items.RemoveAt(ListBox2.Items.Count - 1);

This code worked for me:
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)

If you only want to clear the list box, you should use the Clear (winforms | wpf | asp.net) method:
ListBox2.Items.Clear()

There is a simple method for deleting selected items, and all these people are going for a hard method:
lstYOURVARIABLE.Items.Remove(lstYOURVARIABLE.SelectedItem)
I used this in Visual Basic mode on Visual Studio.

Here's the code I came up with to remove items selected by a user from a listbox It seems to work ok in a multiselect listbox (selectionmode prop is set to multiextended).:
Private Sub cmdRemoveList_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdRemoveList.Click
Dim knt As Integer = lstwhatever.SelectedIndices.Count
Dim i As Integer
For i = 0 To knt - 1
lstwhatever.Items.RemoveAt(lstwhatever.SelectedIndex)
Next
End Sub

Already tested by me, it works fine
For i =0 To ListBox2.items.count - 1
ListBox2.Items.removeAt(0)
Next

I think your ListBox already clear with ListBox2.Items.Clear(). The problem is that you also need to clear your dataset from previous results with ds6.Tables.Clear().
Add this in your code:
da6 = New SqlDataAdapter("select distinct(component_type) from component where component_name='" & ListBox1.SelectedItem() & "'", con)
ListBox1.Items.Clear() ' clears ListBox1
ListBox2.Items.Clear() ' clears ListBox2
ds6.Tables.Clear() ' clears DataSet <======= DON'T FORGET TO DO THIS
da6.Fill(ds6, "component")
For Each row As DataRow In ds6.Tables(0).Rows
ListBox2.Items.Add(row.Field(Of String)("component_type"))
Next

This worked for me.
Private Sub listbox_MouseDoubleClick(sender As Object, e As MouseEventArgs)
Handles listbox.MouseDoubleClick
listbox.Items.RemoveAt(listbox.SelectedIndex.ToString())
End Sub

This can be also checked. Selected item from the list can be deleted using for loop, but error occurs as soon as list item removed to avoid this problem just jump from the loop and start fresh selected list to be remove.
Private Sub BtnDelete_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles BtnDelete.ClickButtonArea
If LstTest.SelectedIndex > -1 Then
jmp1:
If LstTest.SelectedItems.Count > 0 Then
For i = 0 To LstTest.SelectedItems.Count - 1
For Each SI In LstTest.SelectedItems
LstTest.Items.Remove(SI)
GoTo jmp1
Next
Next
End If
End If
End Sub

Dim ca As Integer = ListBox1.Items.Count().ToString
While Not ca = 0
ca = ca - 1
ListBox1.Items.RemoveAt(ca)
End While

Related

Removing a Duplicate Item from ListBox converted into a string

I have an issue where, when I take the items from my ListBox, and convert them into a single-line string, it duplicates the last item. My goal is for it to take just the items from the ListBox, and convert it into a single line of text, seperated by commas (,).
It took me a while, but I found some code on this thread, and it works for the most part, but the last item is always duplicated when converted to a string. The code that I am using is:
Dim item As Object
Dim List As String
' Other unrelated code
' Credit: T0AD - https://www.tek-tips.com/viewthread.cfm?qid=678275
For Each item In Form1.ListBox1_lstbox.Items
List &= item & ","
Next
'To remove the last comma.
List &= item.SubString(0, item.Length - 0)
' This is weird, but setting item.Length - 1 actually removes two characters.
' Add text to textbox
TextBox1.Text = List
I have a feeling that it has to deal with the code that removes the comma, as it is an &= that calls the item Dim again. But I can't seem to figure out what to do.
An example of the output would be something like this: Item1,Item2,Item3,Item3
When I just want this: Item1,Item2,Item3
Your problem is with this line.
List &= item.SubString(0, item.Length - 0)
You are adding another string to List with the &=. The string you are adding is the final value of item from the For Each loop.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If ListBox1.Items.Count = 0 Then
MessageBox.Show("There are no items in the list box.")
Exit Sub
End If
Dim List As String = ""
For Each item In ListBox1.Items
List &= item.ToString & ","
Next
List = List.Substring(0, List.Length - 1)
TextBox1.Text = List
End Sub
Additional solution provided by #Andrew Morton in comments, which doesn't require the ListBox to contain items.
TextBox1.Text = String.Join(",", ListBox1.Items.Cast(Of Object))

Why does visual basic copy a last empty Column when exporting a DataGridView to Clipboard

Thank you for looking at my problem. ^^
I have a small project with a "Copy to Clipboard" button which doesn't work as intended.
I want to copy all 11 Columns and all 10 Rows but it always adds a 12th empty Column, when I subtract a Column from dgvRandom.ColumnCount than the last Column which is supposed to have content is empty. (Picture to clarify - Green is my intention - Red is the actual state) https://i.stack.imgur.com/zvqpr.png
The code I'm referring to is this:
Private Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
Dim sb As New StringBuilder
For row As Integer = 0 To dgvRandom.RowCount - 1
For col As Integer = 0 To dgvRandom.ColumnCount - 1
sb.Append(dgvRandom(col, row).Value?.ToString)
sb.Append(ControlChars.Tab)
Next
sb.Append(ControlChars.NewLine)
Next
Clipboard.SetDataObject(New DataObject(sb.ToString.Trim))
MsgBox("Copied to Clipboard", MsgBoxStyle.OkOnly)
End Sub
I think it's the final TAB before your line break. To remove it, try changing
sb.Append(ControlChars.Tab)
to
If col<dgvRandom.ColumnCount - 1 then sb.Append(ControlChars.Tab)
or even
If col<dgvRandom.ColumnCount - 1 then
sb.Append(ControlChars.Tab)
else
sb.Append(ControlChars.NewLine)
end if
and then delete the sb.Append(ControlChars.NewLine) after the loop

ArgumentOutOfRangeException on Datagridview with 1 row

I have a strange problem. I have a form with on it 2 unbounded datagridviews and 2 buttons. With the buttons I switch the rows from 1 datagrid to the other.
In the beginning the left datagrid is filled with a number of rows and the right datagrid is empty. So when I click on the button "Add" the selected row from the left datagrid is removed and added to the right datagrid. With the button "Delete" the selected row of the right datagrid is added back to the left datagrid.
When there is only one row in the right datagrid, and I select it to "delete" it, the row is removed from the right datagrid and added to the left without an exception. Now I have a situation where there is only one row in the left datagrid and when I click "Add" to move it to the right datagrid I get an ArgumentOutOfRangeException (index is out of bounds...)
Below is the code which throws the exception
For i As Integer = DgvLeft.SelectedRows.Count - 1 To 0 Step -1
ind = DgvLeft.SelectedRows(i).Index
If ind > 0 Then
DgvLeft.Rows.RemoveAt(ind)
Else
DgvLeft.Rows.Remove(DgvLeft.SelectedRows(i))
End If
Next
So I store the row index in a variable. The first time I used the RemoveAt function and the exception is thrown. To resolve this I added the If-structure and tried the Remove function. But again the exception is thrown.
I don't understand why the exception is thrown. I use the same code for the "delete" button and there it doesn't happen. Also when I store the RowIndex in a variable the index is known, but not when I try to Remove the row.
Can someone help me with this strange problem?
Since the posted for loop is “broken”, I feel it is unnecessary to question what you are trying to accomplish here. However, given what you described where there are two grids and two buttons (Add/Delete) on a form. When the “Add” button is clicked, it moves the “selected rows” from the “left” grid to the “right” grid, and then deletes the “selected rows” rows from the “left” grid. If the “Delete” button is clicked, then the opposite process happens moving the “selected rows” from the right grid to the left grid, then delete the selected rows from the right grid.
If this is correct, then it appears you are making this more complicated than it has to be. This would be much easier if you used a data source of some form. However, to break the above problem down, it appears that two methods may come in handy for what you want to do. The first one could simply add the selected rows from one given grid to another given grid. The next method would simply delete the selected rows from a given grid. With these two methods implemented, the “add” button would be…
AddSelectedRows(dgvLeft, dgvRight)
RemoveSelectedRows(dgvLeft)
The delete button would be…
AddSelectedRows(dgvRight, dgvLeft)
RemoveSelectedRows(dgvRight)
Before I explain the code below, it should be noted that your current posted code is making a huge programming “no-no” and without question is a problem for you. As Mary and others have pointed out, “changing the value of the counter variable in a loop or (as the code does) changing the collection it is looping through is rarely if ever done.”
Try the code below it may make things easier,
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddColumns(dgvLeft)
AddColumns(dgvRight)
FillGrid(dgvLeft)
End Sub
Private Sub FillGrid(dgv As DataGridView)
For i = 0 To 15
dgv.Rows.Add("C0R" + i.ToString(), "C1R" + i.ToString(), "C2R" + i.ToString())
Next
End Sub
Private Sub AddColumns(dgv As DataGridView)
Dim txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col0"
txtCol.HeaderText = "Col 0"
dgv.Columns.Add(txtCol)
txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col1"
txtCol.HeaderText = "Col 1"
dgv.Columns.Add(txtCol)
txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col2"
txtCol.HeaderText = "Col 2"
dgv.Columns.Add(txtCol)
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
AddSelectedRows(dgvLeft, dgvRight)
RemoveSelectedRows(dgvLeft)
End Sub
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
AddSelectedRows(dgvRight, dgvLeft)
RemoveSelectedRows(dgvRight)
End Sub
Private Sub RemoveSelectedRows(dgv As DataGridView)
Dim totalRowsToDelete = dgv.SelectedRows.Count
Dim selectedRow As DataGridViewRow
For i = totalRowsToDelete - 1 To 0 Step -1
selectedRow = dgv.SelectedRows(i)
If (Not selectedRow.IsNewRow) Then
dgv.Rows.RemoveAt(dgv.SelectedRows(i).Index)
End If
Next
End Sub
Private Sub AddSelectedRows(sourceDGV As DataGridView, destinationDGV As DataGridView)
Dim selectedRowCount = sourceDGV.Rows.GetRowCount(DataGridViewElementStates.Selected)
If (selectedRowCount > 0) Then
Dim selectedRow As DataGridViewRow
For i = 0 To selectedRowCount - 1
selectedRow = sourceDGV.SelectedRows(i)
If (Not selectedRow.IsNewRow) Then
destinationDGV.Rows.Add(selectedRow.Cells(0).Value.ToString(),
selectedRow.Cells(1).Value.ToString(),
selectedRow.Cells(2).Value.ToString())
End If
Next
End If
End Sub
You are changing the value of DgvLeft.SelectedRows.Count in your For loop.
Try...
Dim RowCount As Integer = DgvLeft.SelectedRows.Count
For i As Integer = RowCount - 1 To 0 Step -1
I want to thank Mary for her answer, because that made me think about my code. I looked at the code of the "delete" button, where I use the same for loop, and that code doesn't throw an exception. So there must be a difference between the code of my two buttons.
This is an expanded piece of my code in the "add" button:
For i As Integer = DgvLeft.SelectedRows.Count - 1 To 0 Step -1
'fill the array with the row values
For j As Integer = 0 To DgvLeft.Columns.Count - 1
fields(j) = DgvLeft.SelectedRows(i).Cells(DgvLeft.Columns(j).Name).Value
Next
'delete the row in datagrid Left
ind = DgvLeft.SelectedRows(i).Index
If ind > 0 Then
DgvLeft.Rows.RemoveAt(ind)
Else
DgvLeft.Rows.Remove(DgvLeft.SelectedRows(i))
End If
'add the row in datagrid Right
DgvRight.Rows.Add(fields)
Next
In the code snippet above I attempt to remove a row BEFORE I add the array of values from this row to the other datagrid. When I looked at the code of the "delete" button I attempt to remove the row AFTER I add the array of values to the other datagrid.
So I moved this piece of code below the code of adding the array of values and it worked. Probably the index exception is thrown by the array rather than the datagridview.

Index out of range in listbox VB.NET

Consider the following code :
Private Sub DelButton_Click(sender As Object, e As EventArgs) Handles DelButton.Click
If OrderListBox.Text = "" = False Then
For i As Integer = OrderListBox.SelectedIndex To arr.Count - 1
arr.RemoveAt(i)
Next
OrderListBox.Items.Remove(OrderListBox.SelectedItem)
End If
calculate()
End Sub
The program crashes at arr.RemoveAt(i) and displays the following error:
Index was out of range. Must be non-negative and less than the size
of the collection.
First of all, please note that in VB.NET and C#, FOR loops are implemented differently!
In VB.NET, it works like this:
BEFORE the loop starts, you are determining start and end of the loop:
Start = OrderListBox.SelectedIndex
End = arr.Count-1
Then, the loop starts.
It is important to know, that in VB.NET, the end of the loop is NOT calculated again anymore. This is an important difference to C#. In C#, the end of the loop is calculated before each single loop.
And now, in the loop, you are DELETING records from the array.
Therefore, the count of records in the array is DECREASING.
However, your loop is going on, since you have calculated the count of records in the array before the loop started.
Therefore, you are going beyond the range of the array.
You could rewrite your code as follows:
Dim i as Integer
i = OrderListBox.SelectedIndex
while i < arr.Count
arr.RemoveAt(i)
Next
This article covers details about the for loop in VB.NET, especially the section "Technical Implementation": https://msdn.microsoft.com/en-us/library/5z06z1kb.aspx
This error will be thrown when you try to remove an item at an index greater than the size of the collection. i.e when i is greater than arr.Count - 1.
You should make sure that OrderListBox.SelectedIndex is not greater than arr.Count - 1. Because if it does, you remove an item that, well, does not exists.
This code is actually displayed in the MSDN docs. As stated, you should do something like this:
Private Sub RemoveTopItems()
' Determine if the currently selected item in the ListBox
' is the item displayed at the top in the ListBox.
If listBox1.TopIndex <> listBox1.SelectedIndex Then
' Make the currently selected item the top item in the ListBox.
listBox1.TopIndex = listBox1.SelectedIndex
End If
' Remove all items before the top item in the ListBox.
Dim x As Integer
For x = listBox1.SelectedIndex - 1 To 0 Step -1
listBox1.Items.RemoveAt(x)
Next x
' Clear all selections in the ListBox.
listBox1.ClearSelected()
End Sub 'RemoveTopItems
ListBox.SelectedIndex will return a value of negative one (-1) is returned if no item is selected.
You didn't check it in your code.
Change your code to this:
If OrderListBox.SelectedIndex >= 0 And OrderListBox.Text = "" = False Then
EDIT
Your code is this:
For i As Integer = OrderListBox.SelectedIndex To arr.Count - 1
arr.RemoveAt(i)
Next
Let's say your OrderListBox contains 3 items : [A, B, C] and the SelectedIndex is 0
Then your code will:
Remove (0) ===> [B, C]
Remove (1) ===> [B]
Remove (2) ===> Exception!
You need to reverse the loop
For i As Integer = arr.Count - 1 To OrderListBox.SelectedIndex Step -1
arr.RemoveAt(i)
Next

Getting the index of an item inside listview vb.net

how do i get the index of an item inside the listview by looping?
for i = 0 to Listview1.items.count -1
??????????????????
next
so that i can get the index and validate it.
i know how to get the index using selectedindices.
i really wanna know how to get the index in a looping method
just want to clarify
i was working on a listview that have a hotkeys from keypress 0 to 9
when keypress 0 is pressed, item1 will be inserted inside the listview and if i pressed 0 again the quantity column will increment, i manage to do that. but the problem is when i press keypress 1 first (which has the item2) it will go inside the listview then if i press keypress 0 im having an error because of the incriminating of the quantity. i think finding the index and loop it will solve the problem.
this is how i manage to incriment the quantity of the item1 in column 4 or element(3)
Dim quantity As Integer = CInt(cartListView.Items(0).SubItems.Item(3).Text)
quantity = quantity + 1
cartListView.Items(0).SubItems.Item(3).Text = quantity.ToString
of course the index(0) gives me error when the item1 is in the index 1 of the listview
please be reminded that the item1 is static or fixed in the keypress 1. any solution or revision?
Solved:
since the item1 is static, the looping statement that vlad gave does it. it manage to search the item1 and return the index and inserted that index to the element 0 of this code
Dim textSearch = DTfsn.Rows(0)("item1").ToString 'static item for keypress 1
For i = 0 To cartListView.Items.Count - 1
If cartListView.Items(i).Text = textSearch Then
Dim quantity As Integer = CInt(cartListView.Items(i).SubItems.Item(3).Text)
quantity = quantity + 1
cartListView.Items(i).SubItems.Item(3).Text = quantity.ToString
End If
Next
now it can increase its quantity whereever the item1 is positioned in the listview.
starting from this comment
of course. i wanna know how to get the index of a searched item
I'll just guess
if you want to find the index of a specific item (in the example I'm searching for item d)
you can do something like this:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim textSearch = TextBox1.Text 'text to look for
For i = 0 To ListView1.Items.Count - 1
If ListView1.Items(i).Text = textSearch Then
MessageBox.Show("text found at index " & i.ToString)
End If
Next
End Sub