I have a class called optionCode:
Class optionCode
Public description As String
Public optCode As String
End Class
I have a query the returns a list of this optionCode class:
Dim _SelectActiveOptionCodes2 = (From _OptCodes In _EntityModel.tblOptionCodes
Where _OptCodes.fdStatus = "A"
Select New optionCode With {.description = _OptCodes.fdDescription,
.optCode = _OptCodes.fdOptionCode}).ToList()
I want to use this list to populate a listbox where the description is the display field and the option code is the value field.
When using:
sortableOptionCodes = _SelectActiveOptionCodes2
sortedOptionCodes = _SelectActiveOptionCodes2
OptionCodeListBox.DataSource = sortedOptionCodes
The listbox populates, but every entry is "OptionCodeSearch.Form1+optionCode"
I can't figure out how to use the .ValueMember and .DisplayMember functions to get the listbox to load the way I want.
First, ValueMember
and DisplayMember
work off properties: Gets or sets the property to use as the actual value for the items in the System.Windows.Forms.ListControl.
So your class should use Properties not Fields (there are conditions where Fields are treated/handled differently than Properties).
With such classes, it good idea to override ToString so you can specify the default text to display instead of the Type (OptionCodeSearch.Form1+optionCode
):
Class optionCode
Public PROPERTY description As String
Public PROPERTY optCode As String
Public Overrides Function ToString() As String
Return Description ' ????
End Function
End Class
ValueMember
is typically a numeric, but otherwise once you have the List(of optionCode)
ValueMember
and DisplayMember
are used to tell the ListBox
the Property Names:
OptionCodeListBox.DisplayMember = "description"
OptionCodeListBox.ValueMember = "optCode"
Not for nothing, but primitives like that can be made into a generic use-almost-anywhere class:
Public Class Element(Of T)
Public Property Name As String
Public Property Value As T
Friend Sub New(n As String, v As T)
Name = n
Value = v
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Of T
allows you to define the Value data type when you build it:
Dim el As New Element(Of Integer)(textName, intValue)
Your list would then be:
Dim myList As New List(Of Element(Of Integer))
It is a little cumbersome to iterate lists, but VS/Intellisense provide hints:
For Each El As Element(of Integer) in myList(Of Element(Of Integer))
If you are using one of these a lot in a project, you can subclass it:
Public Class optCode
Inherits Element(Of String)
Now, the whole Element(Of String)
part is built into your new optCode
class, making it easier to type, use and remember.
The value of these is that you can use the same class for a collection of Name-Value pairs of string, datetime, integer, decimal etc without coding a new class each time you need something like it.
Edit: This answer is for the web form control. See Plutonix's answer for the windows form control.
I believe what you are looking for are the DataTextField
and DataValueField
properties of the ListBox
.
OptionCodeListBox.DataTextField = "description"
OptionCodeListBox.DataValueField = "optCode"