Adding multiple items to combo box only adds LAST ITEM - vb.net

I'm trying to add multiple items to a combobox but only the last item is showing.
Example:
Dim i as Integer
For i = 0 to 3
AddItemToComboBox(i, i)
Next
Sub AddItemToComboBoxMod(ByVal itmValue, ByVal itmData)
Dim comboSource As New Dictionary(Of String, String)()
comboSource.Add(itmValue, itmData)
cbComboBox.DataSource = New BindingSource(comboSource, Nothing)
cbComboBox.DisplayMember = "Value"
cbComboBox.ValueMember = "Key"
Dim key As String = DirectCast(cbComboBox.SelectedItem, KeyValuePair(Of String, String)).Key
Dim value As String = DirectCast(cbComboBox.SelectedItem, KeyValuePair(Of String, String)).Value
End Sub
BUT at the end, only the last item "3" will be there. 0,1,2 will be missing.
Why?

You're making this too complicated.
Populate the values you want in the list.
THEN set the DataSource property ONCE. In above code, you are setting the DataSource property in each iteration of the loop.
Below is a sample event handler that I put together to demonstrate the concept.
Private Sub cmdPopulate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPopulate.Click
Dim i As Integer
Dim comboSource As New Dictionary(Of String, String)()
For i = 0 To 3
comboSource.Add(i, i)
Next
cbComboBox.DataSource = New BindingSource(comboSource, Nothing)
cbComboBox.DisplayMember = "Value"
cbComboBox.ValueMember = "Key"
End Sub

It looks to me like you are creating a new Dictionary every time you call AddItemToComboBoxMod(). You might want to instantiate it and bind it somewhere else. The add item method should only be appending the key value pair.

Related

add similar first number of listbox to another listbox vb.net

i have items in listbox
like this
0,11,41,50
1,5,66,75
1,10,40,50
2,3,43,50
2,7,63,75
2,11,46,50
i need to add similar start number to 1 item
like this
0,11,41,50
1,5,66,75 * 1,10,40,50
2,3,43,50 * 2,7,63,75 * 2,11,46,50
String.Split() your sets on "," and use the first item as the KEY. Add each set to a Dictionary(Of String, List(Of String)) using that key. Then iterate over the Dictionary and combine the sets using String.Join():
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim buckets As New Dictionary(Of String, List(Of String))
For Each items In ListBox1.Items
Dim key As String = items.split(",")(0)
If Not buckets.ContainsKey(key) Then
buckets.Add(key, New List(Of String))
End If
buckets(key).Add(items)
Next
ListBox2.Items.Clear()
For Each kvp As KeyValuePair(Of String, List(Of String)) In buckets
ListBox2.Items.Add(String.Join(" * ", kvp.Value))
Next
End Sub
Output:

Is there a way to retreive the collection items from Textbox - AutoCompleteCustomSource in vb.net

On executing the below code, I am successfully able to insert an array values into a Textbox AutoCompleteCustomSource.
But I need to be able to read all data back from the AutoCompleteCustomSource too, and put it into an array.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.AutoCompleteMode = AutoCompleteMode.Suggest
TextBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim Arr1 As String() = {"Hello", "How", "Are", "You"}
'Below line of code puts all the array values into TxtBox.AutoCompleteCustomSource
TextBox1.AutoCompleteCustomSource.AddRange(Arr1)
'-------------Need Help on Below-------
'How to read all data from TextBox1.AutoCompleteCustomSource and bring it into an array
Dim MyArr1
MyArr1 = TextBox1.AutoCompleteCustomSource??????????????????????????????????????
End Sub
You can throw a bit of LINQ at it:
Dim items = TextBox1.AutoCompleteCustomSource.Cast(Of String)().ToArray()
The AutoCompleteCustomSource is type AutoCompleteStringCollection, which implements IEnumerable but not IEnumerable(Of T), although every item is guaranteed to be a String. That means that you can call the Cast(Of String) extension method to get an IEnumerable(Of String) and then call ToArray on that to get a String array.
Other options include this:
Dim source = TextBox1.AutoCompleteCustomSource
Dim items(source.Count - 1) As String
source.CopyTo(items, 0)
or you can go really old-school with this:
Dim source = TextBox1.AutoCompleteCustomSource
Dim upperBound = source.Count - 1
Dim items(upperBound) As String
For i = 0 To upperBound
items(i) = source(i)
Next

Get OPCItem from ClientHandles in DataChange Event - OPCAutomation.dll

Is it possible to get the OPCItem from a Group using the ClientHandle value?
Pseudo example:
Dim Server As OPCServer
Dim Groups As OPCGroups
Dim WithEvents Group1 as OPCGroup
Dim ItemGroup as OPCItems
Dim Item as OPCItem
Private Sub Form1_Load(sender as Object, e as EventArgs) Handles MyBase.Load
Server.Connect("MyServer")
Group1 = New OPCGroup()
Group1.Name = "Group1"
Group1.IsSubscribed = True
Group1.OPCItems.Add("Item1", 1)
Server.OPCGroups.Add(Group1)
End Sub
Private Sub Group1_DataChange(TransactionID As Integer, NumItems As Integer, ByRef ClientHandles As Array, ByRef ItemValues As Array, ByRef Qualities As Array, ByRef TimeStamps As Array) Handles Group1.DataChange
Dim Browser as OPCBrowser = Server.CreateBrowser()
Browser.ShowBranches()
Browser.DataType = vbInteger
Browser.ShowLeafs()
Dim qualityValue as Integer
For q As Integer = 1 To Qualities.Length
qualityValue = Qualities.GetValue(n)
If qualityValue = 192 Then
'HERE is where I want to get the OPCItem by using the ClientHandles
'I can use the ClientHandle to get the Value, but I'd also like to get the ItemID to do validation against.
Dim itemClientHandle as Integer = Convert.ToInt32(ClientHandles.GetValue(n))
Dim itemValueByClientHandle as String = ItemValues.GetValue(n).ToString()
End If
Next
'It is possible to use the OPCBrowser to get the Item Names but how do I correlate the two?
Dim itemNames as New List(Of String)
For n As Integer = 1 To OPCBrowser.Count
itemNames.Add(OPCBrowser.Item(i))
Next
' Do More Stuff
End Sub
There is a request to enhance an existing client application to be paused when a value is sent from the client to the OPC Server and wait for the bit tag to switch as in indication the process has finished. This part is built; however, there are multiple items (tags) in the group and there needs to be a way of identifying the correct items bit value was changed.

vb.net - combo box always select the first value

Good day, Can anyone help me with this problem. I have two a combo box for months(01-12) for monthstart and monthend. Now, everytime I select October(10), the value it show is 01. Sorry. I am new in vb.
Is there any alternative way to do this? Any suggestions?
Thanks.
Private Sub ValueComboxformonth()
Dim comboSource As New Dictionary(Of String, String)()
comboSource.Add("01", "January")
comboSource.Add("02", "February")
comboSource.Add("03", "March")
comboSource.Add("04", "April")
comboSource.Add("05", "May")
comboSource.Add("06", "June")
comboSource.Add("07", "July")
comboSource.Add("08", "August")
comboSource.Add("09", "September")
comboSource.Add("10", "October")
comboSource.Add("11", "November")
comboSource.Add("12", "December")
cmbAppliedMonthStart.DataSource = New BindingSource(comboSource, Nothing)
cmbAppliedMonthStart.DisplayMember = "Value"
cmbAppliedMonthStart.ValueMember = "Key"
cmbAppliedMonthEnd.DataSource = New BindingSource(comboSource, Nothing)
cmbAppliedMonthEnd.DisplayMember = "Value"
cmbAppliedMonthEnd.ValueMember = "Key"
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
ValueComboxformonth()
Dim monthkeystart As String = DirectCast(cmbAppliedMonthStart.SelectedItem, KeyValuePair(Of String, String)).Key
Dim monthvaluestart As String = DirectCast(cmbAppliedMonthStart.SelectedItem, KeyValuePair(Of String, String)).Value
Dim monthkeyend As String = DirectCast(cmbAppliedMonthEnd.SelectedItem, KeyValuePair(Of String, String)).Key
Dim monthvalueend As String = DirectCast(cmbAppliedMonthEnd.SelectedItem, KeyValuePair(Of String, String)).Value
End Sub
The value of monthkeystart is 01
The value of monthvaluestart is January
This is due to you calling the ValueComboxformonth method before reading the values. That method resets the datasource for the combo-boxes, and it defaults to the first value.
Try moving that call to the constructor (New method) of the form.
Public Sub New()
...
ValueComboxformonth()
End Sub

Resizing an array at runtime in VB.NET

In my Windows Forms application at runtime I will be resizing an array each time I add an element. So first I must resize to the size + 1, and then add a member to this index. How do I do this?
You could use the ReDim statement, but this really isn't your best option. If your array will be changing sizes often, especially as it sounds like you're just appending, you should probably use a generic List(Of T) or similar collection type.
You can use it just like you use an array, with the addition that adding an item to the end is as easy as MyList.Add(item)
To use a generic list, add Imports System.Collections.Generics to the top of the file. Then, you would declare a new integer list like this:
Dim MyList As New List(Of Integer)()
or a string list like this:
Dim MyList As New List(Of String)()
You should get the idea.
The suggested ReDim's need the Preserve keyword for this scenario.
ReDim Preserve MyArray(n)
Using a generic list is (as suggested) the best idea. If you however want to change the size of an Array, you can use Array.Resize(ByRef arr, newSize).
ReDim is not a good (pretty bad) idea (VB specific legacy, extremely slow).
I would prefer some type of collection class, but if you WANT to use an array do it like this:
Dim arr() As Integer
Dim cnt As Integer = 0
Dim ix As Integer
For ix = 1 To 1000
cnt = cnt + 1
ReDim arr(cnt)
arr(cnt - 1) = ix
Next
You can also make your own collection class. A good programming exercise for new programmers.
Public Class MyList
Private Items() As String
Private No As Integer = 0
Public Sub Add(ByVal NewItem As String)
''Create a temporary new string array
Dim CopyString(No) As String
''Copy values from Global Variable Items() to new CopyString array
For i As Integer = 0 To No - 1
CopyString(i) = Items(i)
Next
''Add new value - NewItem - to CopyString
CopyString(No) = NewItem
''Increment No to No + 1
No += 1
''Copy CopyString to Items
Items = CopyString
'Discard CopyString
CopyString = Nothing
End Sub
Public Sub Show(ByVal index As Integer)
MsgBox(Items(index))
End Sub
End Class
''Now create a form with a TextBox name - txt, Button1 and Button2
Public Class Form1
''Declare txts as a new MyList Class
Private txts As New MyList
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
''Add text to txts which is a MyList Class
txts.Add(txt.Text)
txt.Text = ""
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
''Display value at a specific index
txts.Show(Convert.ToInt16(txt.Text))
txt.Text = ""
End Sub
End Class
Use the ReDim command to specify the new size.
ReDim MyArray(MyArray.Length + 1)
As Joel says, use a list.
Dim MyList As New List(Of String)
Don't forget to change Of String to be Of whichever datatype you're using.
This work for me
Dim Table1 As New DataTable
' Define columns
Table1.Columns.Add("Column1", GetType(System.String))
Table1.Columns.Add("Column2", GetType(System.Int32))
Table1.Columns.Add("Column3", GetType(System.Int32))
' Add a row of data
Table1.Rows.Add("Item1", 44, 99)
Table1.Rows.Add("Item2", 42, 3)
Table1.Rows.Add("Item3", 42, 3)
Table1.Rows.Add("Item4", 42, 3)
Dim arr(-1) As String
For Each dr As DataRow In Table1.Rows
ReDim Preserve arr(arr.Length)
arr(arr.Length - 1) = dr("Column1")
Next