Looping through a list gives me repeation of items, xml serializer - vb.net

I have two lists. Both are made of structures I have defined, and this loop is meant to convert the two. I.e., convert and then add to the second list of the other type. Here is what I have:
Dim tempList As New List(Of CameraTemplateProduct)
tempList.Clear()
For j As Integer = 0 To EditCamerasNEW.templateList.Count - 1
'Set up product object.
Dim temp As New CameraTemplateProduct()
'equal properties
temp.Name = EditCamerasNEW.templateList.Item(j).mac
temp.Bitrate = EditCamerasNEW.templateList.Item(j).bitrate
temp.CamDate = EditCamerasNEW.templateList.Item(j).camdate
temp.CamTime = EditCamerasNEW.templateList.Item(j).camtime
temp.Encoder = EditCamerasNEW.templateList.Item(j).encoder
temp.FPS = EditCamerasNEW.templateList.Item(j).fps
temp.Hostname = EditCamerasNEW.templateList.Item(j).hostname
temp.MD = CBool(EditCamerasNEW.templateList.Item(j).MDen)
temp.OSD = CBool(EditCamerasNEW.templateList.Item(j).OSD)
temp.Resolution = EditCamerasNEW.templateList.Item(j).res
tempList.Add(temp)
Next
'Serialize object to a text file.
Dim x As New XmlSerializer((tempList.GetType))
x.Serialize(objStreamWriter, tempList)
Very straight forward. Copy over each property, then add it to the list. When I'm in the loop, temp's values copy over well. The values are exactly the same as the item in TemplateList. When I step through the loop, tempList is exactly what I expect it to be. Three distinct structures. But after wards I get the exact same number of items, but copies of one of them in my list.
However, the line right after the next loop, the tempList instead is the exact same count as templateList, but each value is exactly the same. So every item has the same name, MD, encoder, etc value.
What I've tried: I've tried changing the line after the next to
Dim x As New XmlSerializer((GetType(List(Of CameraTemplateProduct))))
but it gives the same result.
What am I doing wrong? Is there anything the "templist.gettype" is doing to cause this?
EDIT:
I have found that the temp is not changing property values when it loops, so it stays stuck at the first loop values. Is there a better way to clear or set it? I tried setting it to Nothing, but it gave me NULL assignment error.
EDIT2: So following the comments,
I checked to see if the templatelist items were changing. I added a
Dim test = EditCamerasNEW.templateList(j).mac
for each loop to see that it changed. The value did change. I set the rest of the "templatelist.item(j).x" to just "templatelist(j)" as above, but it didn't stop it from creating a list of repeated values.
EDIT3 Tried the below method to no avail. I'm thinking it is possibly when I create the templist of my class. It may not know how to create a list of the product? I will take any help on that.
tempList.Add(New CameraTemplateProduct With {.Name = EditCamerasNEW.templateList(j).mac, _
.Bitrate = EditCamerasNEW.templateList(j).bitrate, _
.CamDate = EditCamerasNEW.templateList(j).camdate, _
.CamTime = EditCamerasNEW.templateList(j).camtime, _
.Encoder = EditCamerasNEW.templateList(j).encoder, _
.FPS = EditCamerasNEW.templateList(j).fps, _
.Hostname = EditCamerasNEW.templateList(j).hostname, _
.MD = EditCamerasNEW.templateList(j).MDen, _
.OSD = EditCamerasNEW.templateList(j).OSD, _
.Resolution = EditCamerasNEW.templateList(j).res})
Here's a portion of the CameraTemplateProduct definition. It's pretty normal:
Public Class CameraTemplateProduct
Public Shared strhostname As String
Public Shared bOSD As Boolean
Public Shared strbitrate As String
Public Shared strencoder As String
Public Shared bMDen As Boolean 'motion detection enabled
Public Shared strres As String
Public Shared intfps As Integer
Public Shared strcamtime As String
Public Shared strcamdate As String
Public Shared strTemplateName As String
'grab properties
Public Property Name() As String
Get
Name = strTemplateName
End Get
Set(ByVal Value As String)
strTemplateName = Value
End Set
End Property
Public Property Hostname() As String
Get
Hostname = strhostname
End Get
Set(ByVal Value As String)
strhostname = Value
End Set
End Property
Public Property OSD() As Boolean
Get
OSD = bOSD
End Get
Set(ByVal Value As Boolean)
bOSD = Value
End Set
End Property
' code continues

Related

vb.net Set type () ()

I have class sObrazac in which I have
'''<remarks/>
<System.Xml.Serialization.XmlArrayItemAttribute("Primatelji", IsNullable:=false), _
System.Xml.Serialization.XmlArrayItemAttribute("P", IsNullable:=false, NestingLevel:=1)> _
Public Property StranaB() As sPrimateljiP()()
Get
Return Me.stranaBField
End Get
Set
Me.stranaBField = value
End Set
End Property
'''<remarks/>
<System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0"), _
System.SerializableAttribute(), _
System.Diagnostics.DebuggerStepThroughAttribute(), _
System.ComponentModel.DesignerCategoryAttribute("code"), _
System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=true, [Namespace]:="http://e-porezna.porezna-uprava.hr/sheme/zahtjevi/ObrazacJOPPD/v1-1")> _
Partial Public Class sPrimateljiP
Private p1Field As Long
Private p2Field As String
Private p3Field As String
Private p4Field As String
.....
'''<remarks/>
Public Property P1() As Long
Get
Return Me.p1Field
End Get
Set
Me.p1Field = value
End Set
End Property
And now I'm setting the object what I have tried
Dim oPrimatelj As New sPrimateljiP
oPrimatelj.P1 = 1
oPrimatelj.P2 = 00019
oPrimatelj.P3 = 00019
oPrimatelj.P4 = 02994650199 ....
After setting that object I tried to push it into list and from it to array
Dim sList As New List(Of sPrimateljiP)
sList.Add(oPrimatelj)
oObrazac.StranaB = sList.ToArray
But as you know it will throw me
Value of type sPrimateljIP() cannot be converted to sPrimateljIP()()
I'm not quite familiar with two dimension arrays and I'm stuck here...
This may clear my question more. What is this element named P.
Note: I can't make schema, I need to adjust code to it.
Ok i found out what solution may be thanks to comment by Chetan. Use jagged array
Push list to jagged array and set it as object
Dim sList As New List(Of sPrimateljiP)
sList.Add(oPrimatelj)
sList.Add(oPrimatelj)
Dim jaggedArray()() As sPrimateljiP = New sPrimateljiP(0)() {sList.ToArray}
oObrazac.StranaB = jaggedArray

Properties, Arrays and ArrayLists using vb.net

In my code behind in my Web project I have a Property
Public Shared UserAttributes(2) As String
Public Property _UserAttributes(ByVal Index As Integer) As String
Get
Return UserAttributes(Index)
End Get
Set(value As String)
UserAttributes(Index) = value
End Set
End Property
And I also have an ArrayList declared as Friend
Friend UserParameters As New ArrayList
I call my property like that:
_UserAttributes(0) = "parameter1"
_UserAttributes(1) = "parameter2"
_UserAttributes(2) = "parameter3"
UserParameters.Add(UserAttributes)
_UserAttributes(0) = "parameter1,1"
_UserAttributes(1) = "parameter2,1"
_UserAttributes(2) = "parameter3,1"
UserParameters.Add(UserAttributes)
From the above code we may see the two pairs of Attributes having one text each one.
What I need now is:
After I add the three Attributes from my Property to my ArrayList
The second three Attributes of my property NOT to spoil the first one.
Which by now that they are doing
And finally I have two(2) _items in my ArrayList which they have the same text on each _item (which is the last one).
What I need is to write the second (or more) set of Attributes without spoiling the previous _items from ArrayList.
Finally I've made it to solve this puzzle as follows
One Property as ArrayList
Public Property _UserParameters As ArrayList
Get
Return UserParameters
End Get
Set(value As ArrayList)
UserParameters = value
End Set
End Property
Second Property as Array
Public Property _UserAttributes(ByVal Index As Integer) As String
Get
Return UserAttributes(Index)
End Get
Set(value As String)
UserAttributes(Index) = value
End Set
End Property
And from code behind I use this code:
Dim UserAttributes As New Hashtable
Dim key As Object = Nothing
Dim Param As Object = Nothing
Dim myList As New ArrayList
Dim item As Object = UserAttributes
UserAttributes.Add("UserId", "Parametr1")
UserAttributes.Add("UserName", "Parametr2")
UserAttributes.Add("UserMail", "Parametr3")
For Each item In UserAttributes
key = item.Key
Param = item.value
logHandler._UserParameters.Add(key & "^" & Param)
Next
myList.Add(logHandler.UserParameters.ToArray)
UserAttributes.Clear()
logHandler.UserParameters.Clear()
UserAttributes.Add("UserId", "Parametr1-1")
UserAttributes.Add("UserName", "Parametr2-1")
UserAttributes.Add("UserMail", "Parametr3-1")
For Each item In UserAttributes
key = item.Key
Param = item.value
logHandler._UserParameters.Add(key & "^" & Param)
Next
myList.Add(logHandler.UserParameters.ToArray)
The use of HashTable solves my issue, Along with the conversion from HashTable parameters to String
Which add them first to the ArrayList Property
And after that add them to the second ArrayList
And the result of these ArrayList I add it to a Pull Down menu control.
And Why I'm doing all that?
That is because I have many users with the same attributes as keys but deferent values
Good day to all, with many thanks.

Set statement, return empty string if error

From the following link there is an example at the bottom of the page which I have recreated in vb.net.
Before the following function runs, I save some data from a textfile into a dictionary called T.
For example:
Name - T0962
Value - 5.89
Public Shared Function initialization()
'Variables initialization
Dim parts As New List(Of Intialization)
'Add parts to the list.
parts.Add(New Intialization() With {
.PartName = "T0962",
.PartId = T.Item(.PartName))
})
If parts.Exists(Function(p) p.PartName = "T0962") Then
Dim value = parts.Where(Function(p) p.PartName = variable_type).FirstOrDefault()
Msgbox(value.PartId)
End If
End Function
The program works perfectly when I have "T0962" variable. When that variable does not exist in the textfile, it does not exist in the dictionary aswell. Thus, I get an error in the code, because the .PartId fails to be initialized. This is because in that textfile sometimes I have that value sometimes I do not.
After I have analized carefully I have noticed that the error happens in the Property statement, at Set(value As String) to be more exactly.
Public Property PartId() As String
Get
Return m_PartId
End Get
'here the error happens
Set(value As String)
m_PartId = value
End Set
End Property
Is there a way to avoid this in the Set statement? For example when there is an error then return an empty string?
Please let me know if there is something you do not understand.
Ok. Try Below. It works for me.
Dim partName As String
partName = "T0962"
parts.Add(New Intialization() With {
.PartName = partName,
.PartId = T.FirstOrDefault(Function(f) f.Key = partName).Value
})

Readonly in keyvaluepair

Well I have created a program that takes some files (Mp3) and change their tags
recently I wanted to add some new Subs (like: Take the songs name and make every letter in it upercase). The problem is that i use a list with its items to be keyvaluepairs
Public MP3List As New List(Of KeyValuePair(Of String, String))
When i tried to edit the key or value of any Item in that list i get an error (That this is READONLY)
Example:
For Each Song In MP3List
Song.Key = "Something"
Next
I add items like this :
Private Function OpenAFile()
Dim MP3List1 = MP3List
Dim oFileDialog As New OpenFileDialog
oFileDialog.Title = "Επέλεξε ένα MP3 Άρχειο"
oFileDialog.Filter = "MP3 Files|*.mp3|All Files|*.*"
oFileDialog.Multiselect = True
Dim Path As String = ""
Dim Name As String = ""
Dim NewPair As New KeyValuePair(Of String, String)
If oFileDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
For Each sPath In oFileDialog.FileNames
Path = New String(sPath)
Name = New String(Strings.Split(Path, "\").ToList(Strings.Split(Path, "\").ToList.Count - 1))
NewPair = New KeyValuePair(Of String, String)(Name, Path)
If Not MP3List1.Contains(NewPair) Then MP3List1.Add(NewPair)
Next
End If
Return MP3List1
End Function
So the idea is this: Each time i press A button to add a song it will run the function OpenAFile() and it was working fine then . Now that i want to change a key or value i get this error
Thanks for the Help and sorry for bad english
The Keys in a KeyValuePair are readonly because they are often used as the key in a hash table. Changing the key would cause issues where you would lose your item in the hash.
If you want to do something like this, you could always create your own data type that stores a key and value. An overly simplified example would be as follows.
Public Structure PathNamePair
Public Property Path As String
Public Property Name As String
Public Sub New(path As String, name As String)
Me.Path = path
Me.Name = name
End Sub
End Structure
I will note that in order to get better performance with your Contains method, you should also implement IEquatable(Of T), but that's probably beyond the scope of this question. I will also note that it is not best practice to have a ValueType (Structure) that is mutable.

Passing Enum Array or list to Function

I want to compare an enum array to single enum instance.
Introduction
I have a class with an enum type array\list
Public Enum InvalidEmailType
Multiple_Updates
Period_Before_At_Sign
Missing_Dot_Com
End Enum
Public Class CustomerClass
Public CustomerName As String
Public ErrorTypeList = [Enum].GetValues(GetType(InvalidEmailType))
Public ErrorDescription As String
End Class
Depending on what values are added to the list, I want to run specific code.
In order to do this I compare the entire list to a single instance:
If UpdateCustomer.MatchErrorType(customer.ErrorTypeList, InvalidEmailType.Trailing_Period) = True Then
'Run Code
End If
Inside the function I compare the entire list against the single instance.
In other words, I loop through the entire list inside the class and check if the value is there:
Public Shared Function MatchErrorType(CustomerErrortypeList As List(Of InvalidEmailType), EmailError As InvalidEmailType) As Boolean
MatchErrorType = False
Dim Found As InvalidEmailType = CustomerErrortypeList.Where(Function(match) match.ToString = EmailError.ToString).OrderByDescending(Function(match) match.ToString).FirstOrDefault()
If Found > 0 Then
MatchErrorType = True
End If
End Function
Here is the problem:
How do I declare the array\list in the function parameters?
List(Of InvalidEmailType) does not work, as I get a cast error
Unable to cast object of type 'EmailValidationReport.InvalidEmailType[]' to type 'System.Collections.Generic.List`1[EmailValidationReport.InvalidEmailType]'
Set ErrorTypeList to a List(of InvalidEmailType) instead of array.
Public ErrorTypeList = [Enum].GetValues(GetType(InvalidEmailType)) _
.Cast(of InvalidEmailType)().ToList()
or
Dim list = customer.ErrorTypeList.Cast(of InvalidEmailType)().ToList()
If UpdateCustomer.MatchErrorType(list, InvalidEmailType.Trailing_Period) Then
'Run Code
End If
Since you aren't doing anything that is specific to List or Array, you can make your method signature take in an IEnumerable instead of a List. This should be able to handle both List and Array (and a few more types as well).
Public Shared Function MatchErrorType(CustomerErrortypeList As IEnumerable(Of InvalidEmailType), EmailError As InvalidEmailType) As Boolean
Dim Found As InvalidEmailType = CustomerErrortypeList.Where(Function(match) match.ToString = EmailError.ToString).OrderByDescending(Function(match) match.ToString).FirstOrDefault()
MatchErrorType = (Found > 0)
End Function