VBNet Error: Collection was modified; enumeration operation may not execute - vb.net

This is what happened: on the form load of my application i created a background worker to bind collection (records from database filled in the dataset) on my control. but the problem is when the i updated the records on the database it throws an error if i run this procedure again.
If xControl.InvokeRequired Then
Dim MyDelegate As New InitializeDataBinding_Delegate(AddressOf InitializeDataBinding)
Invoke(MyDelegate, New Object() {xControl, xQuery, xPrimaryKey}) ' ERROR HERE SAYING: Collection was modified; enumeration operation may not execute.
Else
Using ds As DataSet = New DataSet()
Using dbAdapter As MySqlDataAdapter = New MySqlDataAdapter(xQuery, ConnectionClass.ConnectionString)
dbAdapter.Fill(ds)
End Using
Dim dvm As DataViewManager = New DataViewManager(ds)
Dim iDataList As DataView = dvm.CreateDataView(ds.Tables(0))
For Each iBind As Binding In xControl.DataBindings
xControl.DataBindings.Remove(iBind)
Next
xControl.DataBindings.Add("EditValue", iDataList, xPrimaryKey)
xControl.Properties.DataSource = iDataList
xControl.EditValue = Nothing
txtStatus.Text = "Ready"
End Using
End If

You have to avoid updation in collection while iterating it using For Each. Use simple For loop instead of For Each.

You can't use a For Each loop to remove items from a diction or KeyValuePair, but you can use a regular for loop, get the key and use the key to remove the item from the list.
For i As Integer = 0 To oDictionary.Count - 1
Dim sKey = m_oDictionary.ElementAt(i).Key
m_oDictionary.Remove(sKey)
Next

Solved by adding:
xControl.DataBindings.Clear()
If xControl.InvokeRequired Then
Dim MyDelegate As New InitializeDataBinding_Delegate(AddressOf InitializeDataBinding)
Invoke(MyDelegate, New Object() {xControl, xQuery, xPrimaryKey}) ' ERROR HERE SAYING: Collection was modified; enumeration operation may not execute.
Else
Using ds As DataSet = New DataSet()
Using dbAdapter As MySqlDataAdapter = New MySqlDataAdapter(xQuery, ConnectionClass.ConnectionString)
dbAdapter.Fill(ds)
End Using
xControl.DataBindings.Clear() 'HERE
Dim dvm As DataViewManager = New DataViewManager(ds)
Dim iDataList As DataView = dvm.CreateDataView(ds.Tables(0))
For Each iBind As Binding In xControl.DataBindings
xControl.DataBindings.Remove(iBind)
Next
xControl.DataBindings.Add("EditValue", iDataList, xPrimaryKey)
xControl.Properties.DataSource = iDataList
xControl.EditValue = Nothing
txtStatus.Text = "Ready"
End Using
End If

Dim index As Integer = 0
opnieuw:
For Each F In openbestand.file
If F.Contains("~$") Then
openbestand.file.Remove(openbestand.file(index))
openbestand.path.Remove(openbestand.path(index))
GoTo opnieuw
Else
index = (index + 1)
End If
Next

If you are going to use a loop, you need to ensure that the index is less than the Count, since the count decreases every time a key element is removed:
Dim i As Integer
For i = 0 To dictionary1.Count - 1
If i <= dictionary1.Count - 1 Then
Dim sKey = dictionary1.ElementAt(i).Key
dictionary1.Remove(sKey)
End If
Next

Related

Conversion of type string " " to double not valid exception in vb.net code

I am trying to upload a csv file that has two records in it.
The below code executed for two times and third time I got this exception----Conversion of type string " " to double not valid
I put a debugger where I found the values of two colums of excel sheet but third time I am getting this exception. Your help is highly appreciated.
Below is the code.
Public Function GetLocationInformation(stream As Stream) As List(Of CsvPropLocation) _
Implements ICsvHandling.GetLocationInformation
If stream Is Nothing Then Return Nothing
Dim locations = New List(Of CsvPropLocation)
Using reader = New StreamReader(stream)
Dim config = New CsvConfiguration(CultureInfo.InvariantCulture) With {
.HasHeaderRecord = True,
.IgnoreBlankLines = False
}
Using csv = New CsvReader(reader, config)
Using dataReader As New CsvDataReader(csv)
Dim dt = New DataTable()
dt.Load(dataReader)
For Each row As DataRow In dt.Rows
Dim propLocation As CsvPropLocation
'find or create a propLocation
If locations.Any(Function(x) x.nLocationNumber = row("LocNum")) Then ######Got exception here ######
propLocation = locations.First(Function(x) x.nLocationNumber = row("LocNum"))
Else
propLocation = New CsvPropLocation(row("LocNum"))
locations.Add(propLocation)
End If
'do building stuff.
Dim building = ParseRowIntoBuilding(row)
propLocation.AddBuilding(building)
Next
End Using
End Using
End Using
Return locations
End Function
Change your line to
Dim number As Double
If Double.TryParse(row("LocNum"), number ) AndAlso locations.Any(Function(x) x.nLocationNumber = number )
This way you make sure number will be evaluated only if it gets a valid value from row("LocNum")
Also keep in mind the Else part must be controlled as New CsvPropLocation(row("LocNum")) probably is expecting a valid Double which isnt inside locations so, change to:
Else If Double.TryParse(row("LocNum"), number ) 'You can check against number = 0
'if zero isn't a valid value for number
'(or initialize number to a known invalid value and check against it)
'if yuo didn't want a double try parse
propLocation = New CsvPropLocation(number)
locations.Add(propLocation)
End If

Datagridview to report viewer using parameter VB.net

I try to copy all columns in my datagridview (DGView7) to my report viewer.
I used this code, but it didn't work
Dim myAL As New ArrayList()
Dim row As List(Of String)
For i As Integer = 0 To Basicfor.DGView7.RowCount() - 1
row = New List(Of String)
For j As Integer = 0 To Basicfor.DGView7.ColumnCount() - 1
row.Add(Basicfor.DGView7.Rows(i).Cells(j).ToString)
Next j
myAL.Add(row)
Next i
Dim Params(0) As ReportParameter
Params(0) = New ReportParameter("Ref", CType(myAL.ToArray(GetType(String)), String()))
Me.ReportViewer1.RefreshReport()
It shows an error. I tried to change to this code string() -> Single(), but single is not defined
Params(0) = New ReportParameter("Ref", CType(myAL.ToArray(GetType(String)), Single()))
Can anyone resolve this? Thanks in advance
You're calling
Params(0) = New ReportParameter("Ref", CType(myAL.ToArray(GetType(String)), String()))
And wanting to pass in an array of strings(). That's my assumption at least
However you're passing an array of list of strings.
Try
Dim myStrings = myAL.Cast(Of List(Of String)).SelectMany(Function(r) r).ToArray()

Get RepositoryItem (As Control) From Devexpress-GridviewCell

I'm using the devexpress Gridcontrol/Gridview which has 4 columns
Name: String
Description: String
Action: RepositoryItemLookUpEdit
Info: RepositoryItemHyperLinkEdit
Right now i want to write a function which updates the Action-column but only if the Value is contained in the datasource of the RepositoryItemLookUpEdit
So i started writing the code and this is how i far i got:
For i As Integer = 0 To GridViewDD.RowCount - 1
Dim j As Integer = i
Dim rItemlookup As RepositoryItemLookUpEdit = CType(GridViewDD.GetRow(i), DataRowView).Item("Actions")
If CType(rItemlookup.DataSource, List(Of String)).Contains(curraction) Then
// Do update of the datasource here (which works)
End If
Next
GridControlDD.RefreshDataSource()
My problem lies at the line:
Dim rItemlookup As RepositoryItemLookUpEdit = CType(GridViewDD.GetRow(i), DataRowView).Item("Actions")
Question:
How can i get the RepositoryItemLookUpEdit of a cell in devexpress (or its datasource)?
Note:
The datasource of my gridview (GridViewDD) is a List And my datasource of the RepositoryItemLookUpEdit in Action is always a List(Of String)
Note 2:
The contents of my datasource may vary from row to row
You can easily get your RepositoryItem from GridColumn.ColumnEdit property.
Here is example:
Dim rItemlookup As RepositoryItemLookUpEdit = GridViewDD.Columns("Action").ColumnEdit
'...
For i As Integer = 0 To GridViewDD.RowCount - 1
Dim j As Integer = i
If CType(rItemlookup.DataSource, List(Of String)).Contains(curraction) Then
'... Do update of the datasource here (which works)
End If
Next
GridControlDD.RefreshDataSource()
I've found it. thanks to 'many' hours of browsing the devexpress-forums. Using Gridviewinfo and GridDataRowInfo you can easily access the controls 'hidden' inside the grid
In my case the code looks as following
Dim gvInfo As GridViewInfo = GridViewDD.GetViewInfo()
Dim rInfo As GridDataRowInfo = gvInfo.RowsInfo.FindRow(i)
Dim rItemlookup As RepositoryItemLookUpEdit = rInfo.Cells(GridViewDragDrop.Columns.Item("Actions")).Editor
you can now use rItemlookup to change or access its properties.
I hope this may be of some use to anyone.

LINQ Query Causing Exit Sub or Swallowing Error

My code is as follows:
Using _EntityModel As New AboveNemaSalesDatabaseEntities()
Dim _SelectActiveOptionCodes = (From _OptCodes In _EntityModel.tblOptionCodes
Where _OptCodes.fdStatus = "A"
Select _OptCodes.fdDescription, _OptCodes.fdOptionCode).ToList()
Dim _SelectActiveOptionCodes2 = (From _OptCodes In _EntityModel.tblOptionCodes
Where _OptCodes.fdStatus = "A"
Select New optionCodes With {.description = _OptCodes.fdDescription,
.optionCode = _OptCodes.fdOptionCode})
sortableOptionCodes = _SelectActiveOptionCodes2
sortedOptionCodes = _SelectActiveOptionCodes2
OptionCodeListBox.DataSource = sortedOptionCodes
OptionCodeListBox.DisplayMember = "fdDescription"
OptionCodeListBox.ValueMember = "fdOptionCode"
End Using
The first query works fine and returns a list in the format [index]{description = "descritption here", optionCode = "option code here"}
The second query creates but when it is called to save to my custom class the program exits the sub or swallows an error. Stepping through the code, the line starting with sortedOptionCodes and after never runs.
The main issue I was dealing with is that my query was producing a list of optionCodes and my variable was not prepared to store this.
Old variables:
Dim sortableOptionCodes As optionCodes
Dim sortedOptionCodes As optionCodes
New variables:
Dim sortableOptionCodes As List(Of optionCodes)
Dim sortedOptionCodes As List(Of optionCodes)
I also added a .ToList() function to the end of the second query.

how do i initialize my arraylist

I have a function that adds items to my arraylist. my problem is that it only holds one item at a time since it is reinitializing the array lit every time I click my button. what is the syntax in VB to only initialize the array if it has not been created yet?
Dim itemSelectAs New ArrayList()
Dim Quantities As New ArrayList()
Dim itemQtyOrdered As Integer
Public Sub ShtickDataList_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles ShtickDataList.ItemCommand
If e.CommandName = "addToCart" Then
Dim itemQuantity As DropDownList = e.Item.FindControl("QuantityDropDown")
itemQtyOrdered = itemQuantity.SelectedValue
ItemSelect.Add(e.CommandArgument)
Quantities.Add(itemQtyOrdered)
Session("itemInCart") = ItemSelect
Session("quantities") = Quantities
viewInvoice()
End If
End Sub
Protected Sub viewInvoice()
Dim itemSelected As ArrayList = DirectCast(Session("itemInCart"), ArrayList)
Dim QuantityofItem As ArrayList = DirectCast(Session("quantities"), ArrayList)
Dim conn As SqlConnection
Dim comm As SqlCommand
Dim reader As SqlDataReader
Dim purimConnection2 As String = ConfigurationManager.ConnectionStrings("Purim").ConnectionString
conn = New SqlConnection(purimConnection2)
comm = New SqlCommand("SELECT ProductName FROM Products WHERE ProductID = #ProductID", conn)
Dim i As Integer
For i = 0 To ItemSelect.Count - 1
comm.Parameters.Add("#ProductID", Data.SqlDbType.Int)
comm.Parameters("#ProductID").Value = (ItemSelected.Count - 1)
'Next
Try
conn.Open()
reader = comm.ExecuteReader()
ViewCartlink.Text = "View Cart: (" & ItemSelected.Count & ")"
Finally
conn.Close()
End Try
End Sub
First you need to dimension your array list.
Dim array_list as ArrayList()
Then you can instantiate one
array_list = new ArrayList
Or you can combine it into one step:
Dim array_list = new ArrayList()
After that you can add and remove elements from your array list with
array_list.add(obj)
and remove with
array_list.remove(obj)
It looks like your problem is related to accessing the members of an arraylist. New items are always added to the end of an arraylist. To access them directly, you will need their index. If you know the index of the item you want to access use
array_list(i)
If you don't you will need to iterate over the array. To do this you have two options. You can use "for each" or you can use a normal for loop and use array_list.count as your upper bound.
You're recreating your two session values every time you call your button click menu. You need to pull them out of the Session variable and put them in local variables and put them back into the session variable.
Your button method should be:
Public Sub ShtickDataList_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles ShtickDataList.ItemCommand
if isNothing(itemSelect) Then itemSelect = New ArrayList()
if isNothing(itemQtyOrdered) Then itemQtyOrdered= New ArrayList()
If e.CommandName = "addToCart" Then
Dim itemQuantity As DropDownList = e.Item.FindControl("QuantityDropDown")
itemQtyOrdered = itemQuantity.SelectedValue
ItemSelect.Add(e.CommandArgument)
Quantities.Add(itemQtyOrdered)
Session("itemInCart") = ItemSelect
Session("quantities") = Quantities
viewInvoice()
End If
End Sub
And change your Global calls to:
Dim itemSelect As ArrayList() = Session("itemInCart")
Dim Quantities As New ArrayList() = Session("quantities")
Define your array outside the button click event. (Form level)
Then in the button click event try this:
If myArrayList Is Nothing then
'initializes the array list only if that hasn't happened yet
myArrayList = new ArrayList
End If
'adds the item to the existing list without causing it to reintialize
myArrayList.add(item)
That way it is initialized if it hasn't been, but not if it already has. If it is initialized at the form level ie... its declared as new already then you can just add to it.
Basically make sure that you aren't calling New for the arrayList in the button click event.
Editing for web form:
You should probably check where you initialize your arrayList. Like in the Page_Load:
If Not Page.IsPostBack Then
myArrayList = New ArrayList
End If
MSDN Postback