【发布时间】:2026-01-08 06:00:01
【问题描述】:
在 C# WinApp 中,如何将 Text 和 Value 同时添加到 ComboBox 的项目中? 我进行了搜索,通常答案是使用“绑定到源”..但就我而言,我的程序中没有准备好绑定源... 我该怎么做这样的事情:
combo1.Item[1] = "DisplayText";
combo1.Item[1].Value = "useful Value"
【问题讨论】:
在 C# WinApp 中,如何将 Text 和 Value 同时添加到 ComboBox 的项目中? 我进行了搜索,通常答案是使用“绑定到源”..但就我而言,我的程序中没有准备好绑定源... 我该怎么做这样的事情:
combo1.Item[1] = "DisplayText";
combo1.Item[1].Value = "useful Value"
【问题讨论】:
您必须创建自己的类类型并覆盖 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());
}
【讨论】:
// Bind combobox to 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;
【讨论】:
你可以像这样使用匿名类:
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;
【讨论】:
List<Object> items = new List<Object>(); 而不是数组,然后我可以在循环中使用方法 items.Add( new { Text = "report A", Value = "reportA" } );。
comboBox.SelectedItem.GetType().GetProperty("Value").GetValue(comboBox.SelectedItem, null)
DataSource 的第二种解决方案,您可以使用组合框的SelectedValue 或SelectedText 属性,因此无需进行任何特殊转换。
您应该在运行时使用dynamic 对象来解析组合框项。
comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";
comboBox.Items.Add(new { Text = "Text", Value = "Value" });
(comboBox.SelectedItem as dynamic).Value
【讨论】:
您可以使用Dictionary Object 而不是创建自定义类来在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;
【讨论】:
这是刚刚想到的方法之一:
combo1.Items.Add(new ListItem("Text", "Value"))
要更改项目的文本或值,您可以这样做:
combo1.Items[0].Text = 'new Text';
combo1.Items[0].Value = 'new Value';
Windows Forms 中没有名为 ListItem 的类。它只存在于ASP.NET 中,因此您需要在使用它之前编写自己的类,就像@Adam Markowitz 在his answer 中所做的一样。
同时检查这些页面,它们可能会有所帮助:
【讨论】:
不知道这是否适用于原始帖子中给出的情况(不要介意这是两年后的事实),但这个例子对我有用:
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);
【讨论】:
//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);
【讨论】:
如果还有人对此感兴趣,这里有一个简单而灵活的组合框项目类,它包含文本和任何类型的值(非常类似于 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,您必须跟踪您用于每个项目的类型,并将其转换为您的代码正确使用它。
我在我的项目中使用它已经有一段时间了。真的很方便。
【讨论】:
我喜欢 fab 的回答,但不想根据我的情况使用字典,所以我替换了一个元组列表。
// set up your data
public static List<Tuple<string, string>> List = new List<Tuple<string, string>>
{
new Tuple<string, string>("Item1", "Item2")
}
// bind to the combo box
comboBox.DataSource = new BindingSource(List, null);
comboBox.ValueMember = "Item1";
comboBox.DisplayMember = "Item2";
//Get selected value
string value = ((Tuple<string, string>)queryList.SelectedItem).Item1;
【讨论】:
使用 DataTable 的示例:
DataTable dtblDataSource = new DataTable();
dtblDataSource.Columns.Add("DisplayMember");
dtblDataSource.Columns.Add("ValueMember");
dtblDataSource.Columns.Add("AdditionalInfo");
dtblDataSource.Rows.Add("Item 1", 1, "something useful 1");
dtblDataSource.Rows.Add("Item 2", 2, "something useful 2");
dtblDataSource.Rows.Add("Item 3", 3, "something useful 3");
combo1.Items.Clear();
combo1.DataSource = dtblDataSource;
combo1.DisplayMember = "DisplayMember";
combo1.ValueMember = "ValueMember";
//Get additional info
foreach (DataRowView drv in combo1.Items)
{
string strAdditionalInfo = drv["AdditionalInfo"].ToString();
}
//Get additional info for selected item
string strAdditionalInfo = (combo1.SelectedItem as DataRowView)["AdditionalInfo"].ToString();
//Get selected value
string strSelectedValue = combo1.SelectedValue.ToString();
【讨论】:
你可以使用泛型类型:
public class ComboBoxItem<T>
{
private string Text { get; set; }
public T Value { get; set; }
public override string ToString()
{
return Text;
}
public ComboBoxItem(string text, T value)
{
Text = text;
Value = value;
}
}
使用简单 int-Type 的示例:
private void Fill(ComboBox comboBox)
{
comboBox.Items.Clear();
object[] list =
{
new ComboBoxItem<int>("Architekt", 1),
new ComboBoxItem<int>("Bauträger", 2),
new ComboBoxItem<int>("Fachbetrieb/Installateur", 3),
new ComboBoxItem<int>("GC-Haus", 5),
new ComboBoxItem<int>("Ingenieur-/Planungsbüro", 9),
new ComboBoxItem<int>("Wowi", 17),
new ComboBoxItem<int>("Endverbraucher", 19)
};
comboBox.Items.AddRange(list);
}
【讨论】:
进一步了解 Adam Markowitz 的回答,这是一种通用方法(相对),只需将组合框的 ItemSource 值设置为 enums,同时向用户显示“描述”属性。 (你会认为每个人都想这样做,这样它就会成为一个 .NET 一个班轮,但事实并非如此,这是我发现的最优雅的方式。
首先,创建这个简单的类,用于将任何 Enum 值转换为 ComboBox 项:
public class ComboEnumItem {
public string Text { get; set; }
public object Value { get; set; }
public ComboEnumItem(Enum originalEnum)
{
this.Value = originalEnum;
this.Text = this.ToString();
}
public string ToString()
{
FieldInfo field = Value.GetType().GetField(Value.ToString());
DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
return attribute == null ? Value.ToString() : attribute.Description;
}
}
其次,在OnLoad 事件处理程序中,您需要根据Enum 类型中的每个Enum 将组合框的源设置为ComboEnumItems 列表。这可以通过 Linq 来实现。然后只需设置DisplayMemberPath:
void OnLoad(object sender, RoutedEventArgs e)
{
comboBoxUserReadable.ItemsSource = Enum.GetValues(typeof(EMyEnum))
.Cast<EMyEnum>()
.Select(v => new ComboEnumItem(v))
.ToList();
comboBoxUserReadable.DisplayMemberPath = "Text";
comboBoxUserReadable.SelectedValuePath= "Value";
}
现在用户将从您的用户友好列表中选择Descriptions,但他们选择的将是您可以在代码中使用的enum 值。
要在代码中访问用户的选择,comboBoxUserReadable.SelectedItem 将是 ComboEnumItem,comboBoxUserReadable.SelectedValue 将是 EMyEnum。
【讨论】:
这里有更好的解决方案;
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());
【讨论】:
类创建:
namespace WindowsFormsApplication1
{
class select
{
public string Text { get; set; }
public string Value { get; set; }
}
}
Form1 代码:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<select> sl = new List<select>();
sl.Add(new select() { Text = "", Value = "" });
sl.Add(new select() { Text = "AAA", Value = "aa" });
sl.Add(new select() { Text = "BBB", Value = "bb" });
comboBox1.DataSource = sl;
comboBox1.DisplayMember = "Text";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
select sl1 = comboBox1.SelectedItem as select;
t1.Text = Convert.ToString(sl1.Value);
}
}
}
【讨论】:
您可以使用此代码将一些项目插入到带有文本和值的组合框中。
C#
private void ComboBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
combox.Items.Insert(0, "Copenhagen");
combox.Items.Insert(1, "Tokyo");
combox.Items.Insert(2, "Japan");
combox.Items.Insert(0, "India");
}
XAML
<ComboBox x:Name="combox" SelectionChanged="ComboBox_SelectionChanged_1"/>
【讨论】:
我遇到了同样的问题,我所做的是添加一个新的ComboBox,其值与第一个索引相同,然后当我更改主体组合时,第二个索引中的索引同时更改,然后我取第二个组合的值并使用它。
这是代码:
public Form1()
{
eventos = cliente.GetEventsTypes(usuario);
foreach (EventNo no in eventos)
{
cboEventos.Items.Add(no.eventno.ToString() + "--" +no.description.ToString());
cboEventos2.Items.Add(no.eventno.ToString());
}
}
private void lista_SelectedIndexChanged(object sender, EventArgs e)
{
lista2.Items.Add(lista.SelectedItem.ToString());
}
private void cboEventos_SelectedIndexChanged(object sender, EventArgs e)
{
cboEventos2.SelectedIndex = cboEventos.SelectedIndex;
}
【讨论】:
这就是 Visual Studio 2013 的做法:
单件:
comboBox1->Items->AddRange(gcnew cli::array< System::Object^ >(1) { L"Combo Item 1" });
多个项目:
comboBox1->Items->AddRange(gcnew cli::array< System::Object^ >(3)
{
L"Combo Item 1",
L"Combo Item 2",
L"Combo Item 3"
});
无需进行类覆盖或包含其他任何内容。是的,comboBox1->SelectedItem 和 comboBox1->SelectedIndex 调用仍然有效。
【讨论】:
这与其他一些答案类似,但很紧凑,如果您已经有一个列表,可以避免转换为字典。
给定一个 Windows 窗体上的 ComboBox“组合框”和一个具有 string 类型属性 Name 的类 SomeClass,
List<SomeClass> list = new List<SomeClass>();
combobox.DisplayMember = "Name";
combobox.DataSource = list;
这意味着 SelectedItem 是来自list 的SomeClass 对象,combobox 中的每个项目都将使用其名称显示。
【讨论】:
DisplayMember...我总是忘记它的存在。在我关注这个属性之前,我已经习惯了我找到的解决方案,而且它并不总是有帮助。并非所有类都有Name 或Tag 属性,或者具有可以任意用作显示文本的字符串属性。
base.Method(); 的方法),您还必须创建您希望添加到组合框或列表框的每种不同类型的派生类。我制作的课程很灵活,您可以毫不费力地使用任何类型。看看下面我的答案,告诉我你的想法:)
如果只需要最终值作为(字符串),这是一个非常简单的 Windows 窗体解决方案。项目的名称将显示在组合框中,并且可以轻松比较所选值。
List<string> items = new List<string>();
// populate list with test strings
for (int i = 0; i < 100; i++)
items.Add(i.ToString());
// set data source
testComboBox.DataSource = items;
并在事件处理程序上获取所选值的值(字符串)
string test = testComboBox.SelectedValue.ToString();
【讨论】:
using (SqlConnection con = new SqlConnection(insertClass.dbPath))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter(
"SELECT CategoryID, Category FROM Category WHERE Status='Active' ", con))
{
//Fill the DataTable with records from Table.
DataTable dt = new DataTable();
sda.Fill(dt);
//Insert the Default Item to DataTable.
DataRow row = dt.NewRow();
row[0] = 0;
row[1] = "(Selecione)";
dt.Rows.InsertAt(row, 0);
//Assign DataTable as DataSource.
cboProductTypeName.DataSource = dt;
cboProductTypeName.DisplayMember = "Category";
cboProductTypeName.ValueMember = "CategoryID";
}
}
con.Close();
【讨论】: