vb.net 在没有数据源的 ComboBox 上设置 DisplayMember 和 ValueMember

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38206678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 19:58:49  来源:igfitidea点击:

Set DisplayMember and ValueMember on ComboBox without DataSource

.netvb.netcombobox

提问by genespos

I would like to have a DisplayMemberand a ValueMemberon a ComboBoxwhich has only 4 values and they are always the same.

我希望 aDisplayMember和 aValueMemberComboBox只有 4 个值,并且它们始终相同。

Is it possible without using a DataTableas DataSourceand without creating a class?

是否可以不使用DataTableasDataSource和不创建类?

I would like to have something like:

我想要一些类似的东西:

ValueMember= "Fixed"  
DisplayMember= "Specific and unique number"

ValueMember= "Multiple"  
DisplayMember= "Multiple and different numbers"

ValueMember= "Repeated"  
DisplayMember= "One number repeated x times"

回答by ??ssa P?ngj?rdenlarp

Fundamentally, you cant do what you want:

从根本上说,你不能做你想做的事:

ValueMember= "Fixed"  
DisplayMember= "Specific and unique number"

Value-and DisplayMemberare not for specifying the literal values, but are used to indicate the Property Namesin something else (like a class).

Value-并且DisplayMember不是用于指定文字值,而是用于指示其他事物(如类)中的属性名称



Without using a DataSource(title) is not the same as not using a class (question text). There are alternatives to creating a class:

不使用DataSource(标题)与不使用类(问题文本)不同。有创建类的替代方法:

Existing NET Types

现有的 NET 类型

You could use the existing NET KeyValuePairclass to link a value with a name:

您可以使用现有的 NETKeyValuePair类将值与名称链接:

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 Tupleas explained in another answer

没有数据源 - 数据在项目集合中。Tuple在另一个答案中也有解释



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 Enummakes much more sense:

使用一个字符串作为另一个字符串的键是很奇怪的。通常在代码中,您会想要一些不太容易因拼写错误而出错的东西。在某处键入“Fized”会破坏您的代码。AnEnum更有意义:

Private Enum ValueStyle
    Specific = 0
    Multiple = 1
    Repeated = 2
End Enum

Now, you can create a Listwhich links a description for the user and the Enumconstants:

现在,您可以创建一个List链接用户描述和Enum常量的链接:

' 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 Enumvalues are not sequential (e.g. {8, 65, 99}), the list would have to be built differently.

这将创建一个匿名类型- 一个没有类的对象 - 具有映射到枚举和描述数组的 Name 和 Value 属性。如果Enum值不是连续的(例如 {8, 65, 99}),则必须以不同的方式构建列表。

This creates a temporary collection of Anonymous Typeobjects and assigns it as the DataSource. You wont be able to access the Nameand Valueproperties 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 SelectedValuechanged event:

这将创建匿名类型对象的临时集合并将其分配为数据源。您将无法访问其他方法中的NameValue属性,因为无法将匿名类型传递给其他方法。但是用户将看到所需的文本,NET/VB 将提供作为枚举的值作为SelectedValue. 使用SelectedValue更改的事件:

' 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.

请注意,该代码不是将“Fixed”测试为字符串,而是使用枚举,但仍然具有可读性。

MSDN: Anonymous Types (Visual Basic)

MSDN:匿名类型 (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 Namewith 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.

该类非常简单,在将 anyName与 any相关联时几乎可以无限重用Value。它可以在任意数量的项目中与任意数量的基于列表的控件一起使用。创建和使用它们的列表的代码比使用其他方法更简单。

回答by Fabio

Using some class is a solution, but because you don't want use custom class - use build-in type.

使用某个类是一种解决方案,但因为您不想使用自定义类 - 使用内置类型。

Dim values As New List(Of Tuple(Of String, String))()
values.Add(New Tuple("Fixed", "Specific and unique number"))
values.Add(New Tuple("Multiple", "Multiple and different numbers"))
values.Add(New Tuple("Repeated", "One number repeated x times"))
'and so on...

combobox.ValueMember = "Item1"
combobox.DisplayMember = "Item2"
combobox.DataSource = values

Tuple(Of?T1,?T2) Class

元组(Of?T1,?T2) 类

But for sake of readability my advise use custom class.
Or just in case of reusing custom class is better than Tuple

但为了可读性,我的建议使用自定义类。
或者只是在重用自定义类的情况下比Tuple

回答by bstarr

cbActive is a combobox

cbActive 是一个组合框

Private Sub LoadActiveCB()

    Dim _Active As New List(Of ActiveCB)

    _Active.Add(New ActiveCB With {.Name = "Fixed", .ID = 1})
    _Active.Add(New ActiveCB With {.Name = "Multiple", .ID = 2})
    _Active.Add(New ActiveCB With {.Name = "Repeated", .ID = 3})

    cbActive.DataSource = _Active
    cbActive.DisplayMember = "Name"
    cbActive.ValueMember = "ID"

End Sub

Class ActiveCB
    Property Name As String
    Property ID As Byte
End Class

You'll have to tweak it a bit, change the display and value members, but I believe this may be what you want...?

您必须稍微调整一下,更改显示和值成员,但我相信这可能是您想要的......?

回答by bstarr

I think I get it now... Maybe something like:

我想我现在明白了......也许是这样的:

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim comboSource As New Dictionary(Of String, String)()
        comboSource.Add("1", "Sunday")
        comboSource.Add("2", "Monday")
        comboSource.Add("3", "Tuesday")
        comboSource.Add("4", "Wednesday")
        comboSource.Add("5", "Thursday")
        comboSource.Add("6", "Friday")
        comboSource.Add("7", "Saturday")
        ComboBox1.DataSource = New BindingSource(comboSource, Nothing)
        ComboBox1.DisplayMember = "Value"
        ComboBox1.ValueMember = "Key"
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim key As String = DirectCast(ComboBox1.SelectedItem, KeyValuePair(Of String, String)).Key
        Dim value As String = DirectCast(ComboBox1.SelectedItem, KeyValuePair(Of String, String)).Value
        MessageBox.Show(key & "   " & value)
    End Sub
End Class

Credit: http://net-informations.com/q/faq/combovalue.html

信用:http: //net-informations.com/q/faq/combovalue.html

回答by Alex Alvarez

Given a IList of anonymous types pointing to a database entities in VB, I use it to build an anonymous list with one member pointing to the db entity object (PO) and another to a composite of the values in the entity (Display):

给定一个指向 VB 中数据库实体的匿名类型 IList,我使用它来构建一个匿名列表,其中一个成员指向 db 实体对象 (PO),另一个成员指向实体中的值的组合 (Display):

Dim aList = _BO_Data.Lines
       .Select(Function(PO) ew With {.ACBond = PO, .Display = (PO.Product.Code_item & " - " & PO.Product.Descr)}).ToList()

Combobox_Code_Product.DataSource = aList
Combobox_Code_Product.DisplayMember = "Display"
Combobox_Code_Product.ValueMember = "ACBond"

Then the combobox SelectedItem is the ACBond object and the what I see in the list is the mix of the code and the description of the product.

然后组合框 SelectedItem 是 ACBond 对象,我在列表中看到的是代码和产品描述的组合。