Fundamentally, you cant do what you want:
ValueMember= "Fixed"
DisplayMember= "Specific and unique number"
Value-
and DisplayMember
are not for specifying the literal values, but are used to indicate the Property Names in something else (like a class).
Without using a DataSource
(title) is not the same as not using a class (question text). There are alternatives to creating a class:
Existing NET Types
You could use the existing NET KeyValuePair
class to link a value with a name:
cbox.Items.Add(New KeyValuePair(Of String, String)("Specific",
"Specific and unique number"))
cbox.Items.Add(New KeyValuePair(Of String, String)("Multiple",
"Multiple and different numbers"))
cbox.Items.Add(New KeyValuePair(Of String, String)("Repeated",
"One number repeated x times"))
cbox.ValueMember = "Key"
cbox.DisplayMember = "Value"
There is no DataSource - the data is in the items collection. There is also Tuple
as explained in another answer
Anonymous Type
Using one string as the key for another string is a quite odd. Typically in code you would want something less prone to errors from typos. Typing "Fized" somewhere breaks your code. An Enum
makes much more sense:
Private Enum ValueStyle
Specific = 0
Multiple = 1
Repeated = 2
End Enum
Now, you can create a List
which links a description for the user and the Enum
constants:
' fuller text descr of the enum for the user
Dim descr As String() = {"Specific and unique number",
"Multiple and different numbers",
"One number repeated x times"}
' get enum values into an array of ValueStyle
Dim values = [Enum].GetValues(GetType(ValueStyle)).Cast(Of ValueStyle).ToArray
' create a List of anon objects from the descr() and values()
Dim lst = values.Select( Function (q) New With
{.Value = q, .Name = descr (q)}
).ToList()
cboPicker.ValueMember = "Value"
cboPicker.DisplayMember = "Name"
cboPicker.DataSource = lst
This creates an Anonymous Type - an object without a class - with a Name and Value property mapped to the Enum and description array. If the Enum
values are not sequential (e.g. {8, 65, 99}), the list would have to be built differently.
This creates a temporary collection of Anonymous Type objects and assigns it as the DataSource. You wont be able to access the Name
and Value
properties in other methods because anonymous type cant be passed to other methods. But the user will see the desired text and NET/VB will provide the value as that enum as the SelectedValue
. Using the SelectedValue
changed event:
' name user sees == cboPicker.Text
' value == cboPicker.SelectedValue boxed as Object
Dim userChoice As ValueStyle = CType(cboPicker.SelectedValue, ValueStyle)
If userChoice = ValueStyle.Specific Then
'...
ElseIf userChoice = ValueStyle.Repeated Then
'...
End If
Notice that rather than testing "Fixed" as a string, the code uses the enum but is still every bit as readable.
MSDN: Anonymous Types (Visual Basic)
Those fit the criteria of not needing a new class, but consider:
Friend Class NameValuePair
Public Property Name As String
Public Property Value As Int32
Public Sub New(n As String, v As Int32)
Name = n
Value = v
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
The class is very simple and is almost infinitely reusable in associating any Name
with any Value
. It could be used with any number of list based controls, in any number of projects. The code to create and use a list of them is simpler than using the other methods.