I'm currently trying to make a drop box (Combobox) for currencies for a winform. Here's what I have so far:
But I noticed that there is a special option for the Databound version of a drop down box. So I was wondering if it was possible to create something similar to this without resorting to do a comparison against the entire string or creating a table in a database.
List and Comboboxes can contain objects rather than simply strings. Rather than defining the contents in the Designer, you can set a List(Of T)
(among others) as the DataSource
. This allows you to display one thing but fetch a different thing such as a value back.
This is so useful, it is not uncommon to have a simple NameValuePair
class to translate a value or code into something user-friendly:
Public Class NVP
Public Property Name As String
Public Property Value As Integer
Public Sub New(n As String, v As Integer)
Name = n
Value = v
End Sub
' what these will display using .ToString:
Public Overrides Function ToString() As String
Return String.Format("{0} ({1})", Name, Value.ToString)
End Function
End Class
Then the code to create a list of these and use it as the source for the combo:
Private myAList As List(Of NVP)
...
myAList = New List(Of NVP)
myAList.Add(New NVP("ziggy", 26))
myAList.Add(New NVP("able", 1))
myAList.Add(New NVP("charlie", 3))
myAList.Add(New NVP("echo", 5))
ComboBox1.DataSource = myAList
ComboBox1.DisplayMember = "Name" ' property name to show the user
ComboBox1.ValueMember = "Value" ' property name to use as the value
Then, using it:
Console.WriteLine("Selection Changed! Item: {0} Value: {1}",
ComboBox1.SelectedItem.ToString,
ComboBox1.SelectedValue.ToString)
Output:
Selection Changed! Item: ziggy (26) Value: 26
Selection Changed! Item: charlie (3) Value: 3
Selection Changed! Item: able (1) Value: 1
Notes:
The benefit to the NameValuePair class is that it keep the data together (and easily accessed) rather then as separate items in different arrays.
The major benefit to using a DataSource
, is that you do not need to make a copy of the data. Rather than copy the Name
values from the list to the Items
collection, the List/ComboBox
uses the same ones that your code does.
SelectedItem
returns an NVP
object (as does .Items(n)
) but they are returned as Object
so you need to cast it back to NameValuePair
to access any properties:
thisItem = CType(ComboBox1.SelectedItem, NVP)
Console.WriteLine(thisItem.Name)
SelectedItem.ToString
invokes the ToString
method on our Type. It might simply print the Name
or whatever you want.
If the list is dynamic - things get added and/or removed from it - then you will probably want to use a BiningList(of T)
instead. Changes to the list will automatically appear in the control (ListBox
, ComboBox
, DatagridView
).
If the list items are dynamic - {"ziggy", 26} might be changed to {"zulu", 98}, then your item class should implement INotifyPropertyChanged
so those changes also automatically show in the UI control.