ComboBox:向项目添加文本和值(无绑定源)

238

在C# WinApp中,我该如何将文本和值同时添加到ComboBox的项中? 我进行了搜索,通常的答案都是使用“绑定到源代码”...但在我的情况下,我的程序中没有准备好的绑定源... 我应该如何实现这样的功能:

combo1.Item[1] = "DisplayText";
combo1.Item[1].Value = "useful Value"
21个回答

418

你需要创建自己的类并重写ToString()方法来返回你想要的文本。这是一个可以使用的简单示例类:

public class ComboboxItem
{
    public string Text { get; set; }
    public object Value { get; set; }

    public override string ToString()
    {
        return Text;
    }
}
下面是其使用的简单示例:
private void Test()
{
    ComboboxItem item = new ComboboxItem();
    item.Text = "Item text1";
    item.Value = 12;

    comboBox1.Items.Add(item);

    comboBox1.SelectedIndex = 0;

    MessageBox.Show((comboBox1.SelectedItem as ComboboxItem).Value.ToString());
}

4
我们真的需要这个新类ComboboxItem吗?我认为已经存在一个名为ListItem的类了。 - Amr Elgarhy
19
我认为这可能只在ASP.NET中可用,而不是WinForms。 - Adam Markowitz
1
不是的。该项是一种单独的类型,仅用于存储项目的数据(文本、值、对其他对象的引用等)。它不是ComboBox的后代,极少情况下会是。 - Adam Markowitz
1
一旦你有了ComboboxItem类,你可以以更简单的方式添加它们: comboBox1.Items.Add(new ComboboxItem {Text = "项目文本1", Value = 12 }); - Martin
5
我们如何获取"SelectedValue"或基于值选择项目...请回复。 我们该怎样获得"SelectedValue"或者根据数值来选择一个项目...请回复。 - Alpha Gabriel V. Timbol
显示剩余6条评论

212
// Bind combobox to a dictionary.
Dictionary<string, string> test = new Dictionary<string, string>();
        test.Add("1", "dfdfdf");
        test.Add("2", "dfdfdf");
        test.Add("3", "dfdfdf");
        comboBox1.DataSource = new BindingSource(test, null);
        comboBox1.DisplayMember = "Value";
        comboBox1.ValueMember = "Key";

// Get combobox selection (in handler)
string value = ((KeyValuePair<string, string>)comboBox1.SelectedItem).Value;

4
工作完美,这应该是选定的答案。但是我们不能使用comboBox1.SelectedText而不是强制转换.SelectedItem并获取.Value吗? - Jeffrey Goines
@fab,你如何通过特定的键在组合框中查找项目? - Smith
是否可以根据字典键在组合框中选择一个项目?例如选择键3,那么键为3的项目将被选中。 - Dror
这种方法在vs2015中已不再适用。抛出的异常是无法绑定到新的DisplayMember和ValueMember。 - Plater

137

您可以像这样使用匿名类:

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

comboBox.Items.Add(new { Text = "report A", Value = "reportA" });
comboBox.Items.Add(new { Text = "report B", Value = "reportB" });
comboBox.Items.Add(new { Text = "report C", Value = "reportC" });
comboBox.Items.Add(new { Text = "report D", Value = "reportD" });
comboBox.Items.Add(new { Text = "report E", Value = "reportE" });

更新: 尽管上面的代码可以在组合框中正确显示,但您将无法使用 ComboBox SelectedValue SelectedText 属性。 为了能够使用这些属性,请按以下方式绑定组合框:

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

var items = new[] { 
    new { Text = "report A", Value = "reportA" }, 
    new { Text = "report B", Value = "reportB" }, 
    new { Text = "report C", Value = "reportC" },
    new { Text = "report D", Value = "reportD" },
    new { Text = "report E", Value = "reportE" }
};

comboBox.DataSource = items;

17
我想稍微修改一下,因为程序员可能需要与此同时使用for循环。我使用了一个列表而不是数组 List<Object> items = new List<Object>(); 然后我能够在循环中使用方法 items.Add( new { Text = "report A", Value = "reportA" } ); - Andrew
1
安德鲁,你能让 List<Object> 与 SelectedValue 属性一起工作吗? - Peter PitLock
@Venkat,comboBox.SelectedItem.GetType().GetProperty("Value").GetValue(comboBox.SelectedItem, null) - Optavius
3
如果您使用设置“DataSource”的第二个解决方案,您可以使用组合框的“SelectedValue”或“SelectedText”属性,因此无需进行任何特殊转换。 - JPProgrammer

51

您应该使用dynamic对象在运行时解析组合框项目。

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

comboBox.Items.Add(new { Text = "Text", Value = "Value" });

(comboBox.SelectedItem as dynamic).Value

2
这比创建一个单独的类并覆盖ToString()要好得多。 - Don Shrout
1
动态特性仅适用于C# 4及更高版本。(我认为是.NET 4.5) - MickeyfAgain_BeforeExitOfSO
简单且更快速的编写!我在VB.net中为SelectedValue做了这个: Dim Value As String = CType(Me.SectionIDToComboBox.SelectedItem, Object).Value - Hannington Mambo
2
如何使用“Value”设置正确的组合框项目? - Dave Ludwig
2
这个在2022年末仍然是最简单的... - Ed Graham

22

您可以使用 Dictionary 对象来代替创建自定义类,用于向 Combobox 添加文本和值。

Dictionary 对象中添加键和值:

Dictionary<string, string> comboSource = new Dictionary<string, string>();
comboSource.Add("1", "Sunday");
comboSource.Add("2", "Monday");

将源Dictionary对象绑定到Combobox
comboBox1.DataSource = new BindingSource(comboSource, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";

获取键和值:

string key = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Key;
string value = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Value;

完整源代码:ComboBox 文本和值


16

这是我想到的一种方法:

combo1.Items.Add(new ListItem("文本", "值"))

如果要更改项目的文本或值,您可以这样做:

combo1.Items[0].Text = 'new Text';

combo1.Items[0].Value = 'new Value';

Windows Forms 中并没有名为 ListItem 的类,它只存在于 ASP.NET 中,因此在使用之前您需要编写自己的类,就像 @Adam Markowitz 在 他的答案 中所做的那样。

此外,请查看以下页面,它们可能会有所帮助:


3
如果我没错的话,“ListItem”只在ASP.NET中可用。 - Adam Markowitz
是的 :( 不幸的是它只能使用ASP.net...那么现在我该怎么办呢? - Bohn
那么,组合框中的SelectedValue或SelectedText属性有什么意义呢? - JSON

11

我不知道这个方法是否适用于原帖中提到的情况(更不用说现在已经是两年后了),但是这个示例对我有效:

Hashtable htImageTypes = new Hashtable();
htImageTypes.Add("JPEG", "*.jpg");
htImageTypes.Add("GIF", "*.gif");
htImageTypes.Add("BMP", "*.bmp");

foreach (DictionaryEntry ImageType in htImageTypes)
{
    cmbImageType.Items.Add(ImageType);
}
cmbImageType.DisplayMember = "key";
cmbImageType.ValueMember = "value";
为了读取您的值,您需要将SelectedItem属性转换为DictionaryEntry对象,然后可以评估该对象的Key和Value属性。例如:
DictionaryEntry deImgType = (DictionaryEntry)cmbImageType.SelectedItem;
MessageBox.Show(deImgType.Key + ": " + deImgType.Value);

7
//set 
comboBox1.DisplayMember = "Value"; 
//to add 
comboBox1.Items.Add(new KeyValuePair("2", "This text is displayed")); 
//to access the 'tag' property 
string tag = ((KeyValuePair< string, string >)comboBox1.SelectedItem).Key; 
MessageBox.Show(tag);

6
如果有人仍然对此感兴趣,这里是一个简单灵活的下拉框项目类,它包含任何类型的文本和值(与Adam Markowitz的示例非常相似):
public class ComboBoxItem<T>
{
    public string Name;
    public T value = default(T);

    public ComboBoxItem(string Name, T value)
    {
        this.Name = Name;
        this.value = value;
    }

    public override string ToString()
    {
        return Name;
    }
}

使用<T>比将value声明为object更好,因为使用object时,您需要跟踪每个项目使用的类型,并在代码中对其进行转换才能正确使用。

我在我的项目中使用它已有一段时间了,非常方便。


4
更好的解决方案在这里;
Dictionary<int, string> userListDictionary = new Dictionary<int, string>();
        foreach (var user in users)
        {
            userListDictionary.Add(user.Id,user.Name);
        }

        cmbUser.DataSource = new BindingSource(userListDictionary, null);
        cmbUser.DisplayMember = "Value";
        cmbUser.ValueMember = "Key";

获取数据

MessageBox.Show(cmbUser.SelectedValue.ToString());

虽然我能够填充下拉框,但在 VS2019 中单击它会产生以下错误:请求 COM 可见托管类“ComboBoxUiaProvider”的类接口时发生了 QueryInterface 调用。 - MC9000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接