Properties, Arrays and ArrayLists using vb.net - 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.

Related

Outlook DASL results to datagridview

I am trying to populate the DASL query results (Outlook Table) to a DataGridView in VB.NET Form using below code. Although Outlook table has results, data is not getting populated in the form - no error appears too. Any help please.
Dim oT As Outlook.Table = eFolder.GetTable(strFilter)
oT.Sort("[SentOn]", True)
Me.DataGridView1.DataSource = oT
DataGridView.DataSource has no knowledge of the Outlook.Table COM object. It is your responsibility to convert it into something that the control understands.
Outlook's tables and DataSource instances are entirely different entities. You need to create a binding object in the code on your own extracting the required fields from the Items collection.
The DataGridView class supports the standard Windows Forms data-binding model. This means the data source can be of any type that implements one of the following interfaces:
The IList interface, including one-dimensional arrays.
The IListSource interface, such as the DataTable and DataSet classes.
The IBindingList interface, such as the BindingList class.
The IBindingListView interface, such as the BindingSource class.
As you can see, Outlook doesn't provide anything for that.
For anyone looking for the answer, below is the code
Dim RowCount As Integer = oT.GetRowCount
Dim DtaSet(RowCount, 6) As String
Dim VarArray As Array
VarArray = oT.GetArray(RowCount)
Dim myarr(RowCount) As mystructure
For ix As Integer = 0 To RowCount - 1
myarr(ix) = New mystructure With
{
.From = VarArray(ix, 0).ToString,
.EmailTo = VarArray(ix, 1).ToString,
.CC = VarArray(ix, 2).ToString,
}
Next
DataGridView1.DataSource = myarr
Continues as below:
Structure mystructure
Private mFrom As String
Private mEmailTo As String
Private mCC As String
Public Property From() As String
Get
Return mFrom
End Get
Set(ByVal value As String)
mFrom = value
End Set
End Property
Public Property EmailTo() As String
Get
Return mEmailTo
End Get
Set(ByVal value As String)
mEmailTo = value
End Set
End Property
Public Property CC() As String
Get
Return mCC
End Get
Set(ByVal value As String)
mCC = value
End Set
End Property

Combo Box items - Display Member for List(Of String)?

My project is in Visual Basic. I am trying to create a custom & savable "filter" for a DataGridView using several TextBoxes. Right now, any List(Of String) that is added to the Combo Box is displayed in the box as (Collection). I want my users to be able to select the one they created, so I would like the Lists to have a display name that can be selected in the Combo Box. Here is some of the code.
Dim savedFilter As New List(Of String)
savedFilter.Add(NameTextBox.Text)
savedFilter.Add(AgeTextBox.Text)
savedFilter.Add(NotesTextBox.Text)
ComboBoxSavedFilters.Items.Add(savedFilter)
Is it possible to add a display name for a List?
Or if you are lazy use buid-in generic class Tuple From MSDN.
Create collection of Tuple(Of String, List(Of String)) and use approach suggested by #Plutonix for binding collection to ComboBox
Dim savedFilter As New List(Of Tuple(Of String, List(Of String)))()
savedFilter.Add(
Tuple.Create("default",
New List From {"filter1", "filter2", "filter3"}))
savedFilter.Add(
Tuple.Create("Blue ones",
New List From {"filter4", "filter5"}))
savedFilter.Add(
Tuple.Create("Old ones",
New List From {NameTextBox.Text, AgeTextBox.Text, NotesTextBox.Text}))
With ComboBoxSavedFilters
.DisplayMember = "Item1" 'Name of first property in Tuple type
.ValueMember = "Item2" 'Name of second property in Tuple type -List
.DataSource = savedFilter
End With
Then SelectedValue will contain currently selected filter's collection,
which can be accessed like that
Dim filter As List(Of String) =
DirectCast(Me.ComboBoxSavedFilters.SelectedValue, List(Of String))
You could setup under My.Settings a StriingCollection
Initializing (you can omit the items added if so desired)
If My.Settings.Filters Is Nothing Then
My.Settings.Filters = New StringCollection() From {"One", "Two"}
End If
Setup items in a ComboBox
ComboBox1.Items.AddRange(My.Settings.Filters.Cast(Of String).ToArray)
Adding an item
My.Settings.Filters.Add(Now.ToShortDateString)
You can remove and clear items too.
Provide a Display Member for List(Of String)
Apparently, these are less a collection of filters than a collection of criteria or clauses for one Filter:
I condensed the code in the question, but there are 14 fields that can be filtered and there are multiple filters that can be applied on one field.
For the multiples per field, I am not sure I would want to store those individually, but keep the field criteria together. So, if you want to apply a name to these, a class would not only do that but could help manage the filter elements:
Public Class SuperFilter
Public Property Name As String
Public Property Elements As SortedList
Public ReadOnly Property FilterText As String
Get
Return GetFilterText()
End Get
End Property
Public Sub New(n As String)
Name = n
Elements = New SortedList
End Sub
Public Sub AddItem(filter As String)
Elements.Add(Elements.Count, filter)
End Sub
Public Sub InsetAt(index As Int32, filter As String)
Elements.Add(index, filter)
End Sub
Private Function GetFilterText() As String
Dim els(Elements.Count - 1) As String
Elements.Values.CopyTo(els, 0)
Return String.Join(" ", els)
End Function
Public Overrides Function ToString() As String
Return String.Format("{0} ({1})", Name, Elements.Count.ToString)
End Function
End Class
You would need to add methods and properties like Remove and Count but this should be enough to demonstrate. I am not sure about the SortedList, a Dictionary using the field name might be better, but something to control the order seems worthwhile. I am also unsure I would expose the Elements collection - managing it might be better left to the class.
Hopefully, the Combo displaying a set of these (as opposed to the filter elements/clauses) is the goal.
Private filters As New List(Of SuperFilter)
Add filter items to the list:
Dim item As New SuperFilter("Default")
item.AddItem("Id = 7")
filters.Add(item)
item = New SuperFilter("Blue Ones")
item.AddItem("Color = Blue")
filters.Add(item)
item = New SuperFilter("Complex")
item.AddItem("[Name] like %Bob% OR [Name] like %Alice%")
item.AddItem("AND Color = 'Blue'")
item.AddItem("AND Active=True")
item.AddItem("AND AccessRequired < 3")
item.AddItem("AND DateAdded > #2/11/2010#")
item.AddItem("AND CreatedBy = 'ziggy'")
filters.Add(item)
cbo1.DataSource = filters
cbo1.DisplayMember = "Name"
cbo1.ValueMember = "FilterText"
The value member could be the Elements - the collection of filter clauses, or it could be the query text. The GetFilterText method joins them together for you as part of what a filter manager class could/should:
For n As Int32 = 0 To filters.Count - 1
Console.WriteLine("Name: {0} Count: {1}{2}Text:{3}", filters(n).Name,
filters(n).Elements.Count,
Environment.NewLine, filters(n).FilterText)
Next
Result:
Name: Default Count: 1
Text:Id = 7
Name: Blue Ones Count: 1
Text:Color = Blue
Name: Complex Count: 6
Text:[Name] like %Bob% OR [Name] like %Alice% AND Color = 'Blue' AND Active=True AND AccessRequired < 3 AND DateAdded > #2/11/2010# AND CreatedBy = 'ziggy'
If you use "Elements" as the ValueMember you will get back the collection.
The combo displays the Name for the user. On the right, a label displays the ValueMember in this case, it is the FilterText or joined Elements. As I said, you could get back the actual collection as the SelectedValue instead, but that is available as part of SelectedItem.
If savable means beyond the life of the application instance, that is another question, but these are very easily serialized.

LongListSelector selecteditem

I have a LongListSelector in an .xaml and I am able to fill it by binding to a an ItemSource when the source is filled by a DataContext using a single table from my SQL Server CE database like this:
Dim row = (From rows In db.Hub
Order By rows.HubID Descending
Select rows).ToList()
Me.MainLongListSelector.ItemsSource = row
I am thus able to get the ID of the selected item as follows:
HubID = CType(MainLongListSelector.SelectedItem, Hub).HubID
I am also able to bind to a 'query' DataSource as follows:
Dim row = (From ac In db.Activity
Join at In db.ActivityType On ac.ActivityTypeID Equals at.ActivityTypeID
Select New With {.ID = ac.ActivityID,
.Title = ac.Activity1}).ToList()
Me.MainLongListSelector.ItemsSource = row
however, since this is not referring to a specific table in the DataContext, I cannot get the ID using the above code, ie:
Dim ActID = CType(MainLongListSelector.SelectedItem, Activity).ActivityID '- returns nothing
How should I get the value(s) of selectedItem in this case?
NB: I have created the anonymous fields (.ID and .Title) because those are the names I have bound in the xaml, so the LongListSelected gets populated without writing extra code.
Thanks
Phew!!
I discovered that two things:
this HubID = CType(MainLongListSelector.SelectedItem, Hub).HubID is calling a List (Of DataContext), while in the second scenario above I am using a List (Of Anonymous). So I searched for List (Of Anonymous) and this came up!
I now know I can create a class for List (Of Anonymous) and properly name its properties, thus make it available outside its methods, like in my 'query' question above.
So the answer is I created the class for my anonymous list, declared its properties
Public Class AnonList
Private _id As Integer
Public Property ID() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Private _title As String
Public Property Title() As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
Private _desc As String
Public Property Desc() As String
Get
Return _desc
End Get
Set(ByVal value As String)
_desc = value
End Set
End Property
End Class
and therefore assigned them to the ItemSource values,
Select New AnonList With {.ID = ac.ActivityID,
thus being able to get the SelectedItem values as required:
ActivityID = CType(MainLongListSelector.SelectedItem, AnonList).ID
Took a bit of determination to figure that out!

Looping through a list gives me repeation of items, xml serializer

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

How Do I loop through this class once I have added items

How do i loop through this class once I add items via this method. Just I am quite new to generic lists so was wonding if someone could point me in right direction in datatables im used to doing the following:
For Each thisentry In dt.rows
Next
What do I use in collections
Calling Code
Calling this in my delciarations of main class
Dim infoNoProductAvail As List(Of infoProductsNotFound) = New List(Of infoProductsNotFound)()
this is how i am adding the files but I have checked in the routine and the count for the list is at 2 products
If medProductInfo.SKU.SKUID = 0 Then
infoNoProductAvail.Add(New infoProductsNotFound(thisenty2.Item("EAN13").ToString(), True))
End If
this is the class itselfs
Public Class infoProductsNotFound
Public Sub New(tbcode As String, notfound As Boolean)
Me.tagbarcode = tbcode
Me.notfound = notfound
End Sub
Private tagbarcode As String = String.Empty
Private notfound As Boolean
Public Property tbcode() As String
Get
Return tagbarcode
End Get
Set(ByVal value As String)
tagbarcode = value
End Set
End Property
Public Property isNotFound() As Boolean
Get
Return notfound
End Get
Set(ByVal value As Boolean)
notfound = value
End Set
End Property
End Class
Tried
I tried using the following
Function BuildExceptionsForEmail()
Dim retval As String = ""
Dim cnt As Int32 = 0
retval = "The following products are not avialable" & vbCrLf
For Each info As infoProductsNotFound In infoNoProductAvail
retval &= info.tbcode
cnt &= 1
Next
Return retval
but for some reason at this point my info noproductAvail is blank even though in the routine above its sitting at count of 2 what gives?
First I'd shrink that declaration a bit:
Dim infoNoProductAvail As New List(Of infoProductsNotFound)
Next, to iterate there are several options. First (and what you're likely most used to):
For Each info as infoProductsNotFound in infoNoProductAvail
If info.tbCode = "xyz" Then
DoSomething(info)
End If
Next
Or you might want to use lambda expressions (if you're using .Net 3.5 and above I think - might be .Net 4):
infoNoProductAvail.ForEach (Function(item) DoSomething(item))
Remember that generics are strongly typed (unlike the old VB collections) so no need to cast whatever comes out: you can access properties and methods directly.
If infoNoProductAvail(3).isNotFound Then
'Do something
End If
(Not that that is a great example, but you get the idea).
The For Each syntax is the same. It works the same way for all IEnumerable objects. The only "trick" to it is to make sure that your iterator variable is of the correct type, and also to make sure that you are iterating through the correct object.
In the case of the DataTable, you are iterating over it's Rows property. That property is an IEnumerable object containing a list of DataRow objects. Therefore, to iterate through it with For Each, you must use an iterator variable of type DataRow (or one of its base classes, such as Object).
To iterate through a generic List(Of T), the IEnumerable object is the List object itself. You don't need to go to one of it's properties. The type of the iterator needs to match the type of the items in the list:
For Each i As infoProductsNotFound In infoNoProductAvail
' ...
Next
Or:
Dim i As infoProductsNotFound
For Each i In infoNoProductAvail
' ...
Next
Or:
For Each i As Object In infoNoProductAvail
' ...
Next
Etc.