vb.net - combo box always select the first value - vb.net

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

Related

Get a value by index from combobox class

i'm approaching to vbnet from vb6 and i'm triyng to get value from combobox using a class which contains the values i stored in.
here is the class
Private m_ItemText As String
Private m_ItemIndex As Int32
Public Sub New(ByVal strItemText As String, ByVal intItemIndex As Int32)
m_ItemText = strItemText
m_ItemIndex = intItemIndex
End Sub
Public ReadOnly Property ItemIndex() As Int32
Get
Return m_ItemIndex
End Get
End Property
Public ReadOnly Property ItemText() As String
Get
Return m_ItemText
End Get
End Property
I use this method charge the combobox
ComboBox2.Items.Add(New clsComboBoxItem("sometext", 1))
ComboBox2.Items.Add(New clsComboBoxItem("sometext 2", 2))
ComboBox2.Items.Add(New clsComboBoxItem("sometext", 3))
and this on combobox.selectedindexchanged
If ComboBox2.SelectedItem.GetType.ToString = itmCombo.GetType.ToString Then
itmCombo = CType(ComboBox2.SelectedItem, clsComboBoxItem)
MessageBox.Show("Item Text=" & itmCombo.ItemText & " and ItemIndex=" & CStr(itmCombo.ItemIndex))
End If
Can anyone tell help me to understand how get an element by his index stored in the class? Eg writing '2' into a text box, the combo box sould be show "sometext2".
Suppose i want to expand the class adding some values, like m_ItemText2,m_ItemText3 etc, i would learn a method to get all of theese values.
I hope I was clear
Thanks in advance
If you have a DataSource set to a DataTable for your ComboBox, just set the DisplayMember and ValueMember. My test ComboBox is set to DropDownList.
Private Sub FillComboBox()
Dim dt As New DataTable
Using con As New SqlConnection(ConStr),
cmd As New SqlCommand("Select FlavorID,FlavorName From Flavors", con)
con.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
ComboBox1.DisplayMember = "FlavorName"
ComboBox1.ValueMember = "FlavorID"
ComboBox1.DataSource = dt
End Sub
To display the the values
To display the Text cast to DataRowView (that is the object that is in the Item), provide the field you want and call ToString.
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
MessageBox.Show(ComboBox1.SelectedValue.ToString)
MessageBox.Show(DirectCast(ComboBox1.SelectedItem, DataRowView)("FlavorName").ToString)
End Sub
If you are adding items one by one, you can still set the DisplayMember and ValueMember.
'https://stackoverflow.com/questions/38206678/set-displaymember-and-valuemember-on-combobox-without-datasource
Private Sub SomeFormsLoadEvent()
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Ultra-fast", 600))
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Fast", 300))
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Medium", 150))
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Slow", 75))
ComboBox1.DisplayMember = "Key"
ComboBox1.ValueMember = "Value"
ComboBox1.DataSource = ComboBox1.Items
End Sub
I found it a bit more complicated to display the text. I had to cast the item to its underlying type (KeyValuePair) then ask for the Key value.
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
MessageBox.Show(ComboBox1.SelectedValue.ToString)
MessageBox.Show(DirectCast(ComboBox1.SelectedItem, KeyValuePair(Of String, Integer)).Key)
End Sub
As I understand it you want to store values in a class and display and access them through the combobox. How about this approach:
The class for the values:
Public Class clsValues
Private lstItemTexts As New List(Of String)
Public ReadOnly Property AllValues As List(Of String)
Get
Return lstItemTexts
End Get
End Property
'To initialize class with empty list, items can be added with AddItems
Public Sub New()
End Sub
'To initialize class with items, items can still be added with AddItems
Public Sub New(lstItemTexts As List(Of String))
Me.lstItemTexts = lstItemTexts
End Sub
Public Sub AddItem(item As String)
Me.lstItemTexts.Add(item)
End Sub
Public Function GetItemByIndex(index As Integer) As String
Return lstItemTexts(index)
End Function
Public Function GetIndexByItem(item As String) As Integer
Return lstItemTexts.IndexOf(item)
End Function
End Class
You can declare it and fill values like this:
Private Values As New clsValues()
Values.AddItem("Some Text 1")
Values.AddItem("Some Text 2")
or
Private Values As New clsValues(New List(Of String)({"Some Text 1", "Some Text 2"}))
to get a value from combobox
Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
MessageBox.Show(Values.GetItemByIndex(ComboBox2.SelectedIndex))
End Sub
What #Mary stated is true the ComboBox has values that are useful SEE CODE BELOW
Change gvTxType to be a TextBox to see results when you click on the tvTxType
Private Sub cbTxType_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbTxType.SelectedIndexChanged
If cbTxType.SelectedIndex > -1 Then
'Dim sindex As Integer
'sindex = cbTxType.SelectedIndex
'Dim sitem As String
sitem = CType(cbTxType.SelectedItem, String)
'MsgBox("You Selected " & sitem)
'Index is ZERO based
gvTxType = sitem
End If
End Sub

Passing list to function as parameter

I have a function that will perform work on a list, but I cannot get it to accept more than one datatype. For example:
Public Sub PopulateListBox (objectList as List(of VariantType), ListboxToPopulate as Listbox)
listboxToPopulate.Items.Clear() 'clears the items in the listbox
For Each item In objectList
listboxToPopulate.Items.Add(item.ToString)
Next
End
The problem is that I have lists of different classes, like employee, building address, etc. I cannot pass a List(Of EmployeeClass) because it says it cannot be converted to List(Of VariantType). I have also tried List(Of Object) and the same result.
I will demonstrate the use by first showing you a sample class.
Public Class Coffee
Public Property ID As Integer
Public Property Name As String
Public Property Type As String
Public Sub New(iid As Integer, sname As String, stype As String)
ID = iid
Name = sname
Type = stype
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
I added a parameterized constructor just to make it easy to get a fully populate Coffee. You need to add the .ToString override so the list box will know what to display.
Here is where my List(Of Coffee) comes from.
Private Function FillCoffeeList() As List(Of Coffee)
Dim CoffeeList As New List(Of Coffee)
Using cn As New SqlConnection(My.Settings.CoffeeConnection),
cmd As New SqlCommand("Select Top 10 ID, Name, Type From Coffees;", cn)
cn.Open()
Using reader = cmd.ExecuteReader
Do While reader.Read
Dim c As New Coffee(reader.GetInt32(0), reader.GetString(1), reader.GetString(2))
CoffeeList.Add(c)
Loop
End Using
End Using
Return CoffeeList
End Function
As commented by Hans Passant, change the datatype of objectList to IEnumerable(Of Object).
Public Sub PopulateListBox(objectList As IEnumerable(Of Object), ListboxToPopulate As ListBox)
ListboxToPopulate.Items.Clear() 'clears the items in the listbox
For Each item In objectList
ListboxToPopulate.Items.Add(item)
Next
End Sub
Now I can pass a List(Of Coffee) to the PopulateListBox method.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim CList = FillCoffeeList()
PopulateListBox(CList, ListBox1)
End Sub
I can access the properties of the underlying type be casting.
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim t = ListBox1.SelectedItem.GetType
Select Case t.Name
Case "Coffee"
Dim c = DirectCast(ListBox1.SelectedItem, Coffee)
TextBox1.Text = c.ID.ToString
TextBox2.Text = c.Type
End Select
End Sub
You can add additionsl cases depending on what types you are expecting. There is probably a better way to do this.

Getting Installed Steam Games From Registry

Can someone help me with this error I'm getting? Error14 'Using' operand of type 'System.Collections.Generic.List(Of String)' must implement 'System.IDisposable'
Public Function GetInstalledGames() As Object
Dim enumerator As IEnumerator(Of String) = Nothing
Dim list As List(Of String) = Directory.GetFiles(String.Concat(Me.SteamPath, "\steamapps")).ToList()
Using strs As List(Of String) = New List(Of String)()
enumerator = list.Distinct().GetEnumerator()
While enumerator.MoveNext()
Dim current As String = enumerator.Current
If (current.Contains("appmanifest_") And current.Contains(".acf")) Then
strs.Add(Path.GetFileName(current).Replace("appmanifest_", "").Replace(".acf", ""))
End If
End While
End Using
Return strs
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim enumerator As IEnumerator(Of String) = Nothing
Me.tbOutput.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Me.SteamPath = Conversions.ToString(Me.GetSteamPath())
Using installedGames As List(Of String) = DirectCast(Me.GetInstalledGames(), List(Of String))
enumerator = installedGames.Distinct().GetEnumerator()
While enumerator.MoveNext()
Dim current As String = enumerator.Current
Me.lbGames.Items.Add(current)
End While
End Using
End Sub
Stop writing explicit enumerator loops for no reason
Make your functions return types that make sense instead of Object
Don’t sprinkle Using into code without knowing what it does
Pass data between functions through arguments, not class fields
Private Shared Function GetInstalledGames(steamPath As String) As IEnumerable(Of String)
Dim result As New List(Of String)
For Each name In Directory.GetFiles(Path.Combine(steamPath, "steamapps"))
If name.Contains("appmanifest_") AndAlso name.Contains(".acf") Then
result.Add(Path.GetFileNameWithoutExtension(name).Replace("appmanifest_", ""))
End If
Next
Return result
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs)
Me.tbOutput.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim steamPath As String = Me.GetSteamPath()
For Each current In GetInstalledGames(steamPath).Distinct()
Me.lbGames.Items.Add(current)
Next
End Sub

Adding multiple items to combo box only adds LAST ITEM

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.

in VB Trying to Understand Reflection.. or getting a String to be a Control

I was looking at https://stackoverflow.com/a/4132070/1529149 about reflection..
in Particular this
Public Sub setProperty(ByVal obj As Object, ByVal propName As String, ByVal newValue As Object)
Dim prop As Reflection.PropertyInfo = obj.GetType().GetProperty(propName)
If Not prop Is Nothing AndAlso prop.CanWrite Then
prop.SetValue(obj, newValue, Nothing)
End If
End Sub
But I need to enter the first variable as a string or something dynamic..
I see no point setting
setProperty(FixedObject, "Dynamic Property", "Dynamic Results")
When It would be far more powerful as
setProperty("Dynamic Object", "Dynamic Property", "Dynamic Results")
for example:
Dim billy As String = "Label"
Dim bob As Integer = 1
setProperty(billy+bob, "Text", "Results")
Creates Label1.Text = "results"
Any help on getting something like that? (p.s. I understand I probably have to cast bob as a String somewhere, but I'm still new to VB)
I don't understand why you would want to use Reflection, but this works:
Public Class Form1
Private Sub Form1Load(sender As Object, e As EventArgs) Handles Me.Load
Dim billy As String = "Label"
Dim bob As Integer = 1
Dim label As Object = Me.Controls(billy & bob)
SetProperty(label, "Text", "Results")
End Sub
Public Sub SetProperty(obj As Object, propName As String, newValue As Object)
Dim prop As Reflection.PropertyInfo = obj.GetType().GetProperty(propName)
If Not prop Is Nothing AndAlso prop.CanWrite Then
prop.SetValue(obj, newValue, Nothing)
End If
End Sub
End Class