ComboBox: Adding Text and Value to an Item (no Binding Source)
In C# WinApp, how can I add both Text and Value to the items of my ComboBox? I did a search and usually the answers are using "Binding to a source".. but in my case I do not have a binding source ready in my program... How can I do something like this:
combo1.Item[1] = "DisplayText";
combo1.Item[1].V开发者_StackOverflow社区alue = "useful Value"
You must create your own class type and override the ToString() method to return the text you want. Here is a simple example of a class you can use:
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Text;
}
}
The following is a simple example of its usage:
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;
You can use anonymous class like this:
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" });
UPDATE: Although above code will properly display in combo box, you will not be able to use SelectedValue
or SelectedText
properties of ComboBox
. To be able to use those, bind combo box as below:
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;
You should use dynamic
object to resolve combobox item in run-time.
comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";
comboBox.Items.Add(new { Text = "Text", Value = "Value" });
(comboBox.SelectedItem as dynamic).Value
You can use Dictionary
Object instead of creating a custom class for adding text and value in a Combobox
.
Add keys and values in a Dictionary
Object:
Dictionary<string, string> comboSource = new Dictionary<string, string>();
comboSource.Add("1", "Sunday");
comboSource.Add("2", "Monday");
Bind the source Dictionary object to Combobox
:
comboBox1.DataSource = new BindingSource(comboSource, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
Retrieve Key and value:
string key = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Key;
string value = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Value;
Full Source : Combobox Text nd Value
This is one of the ways that just came to mind:
combo1.Items.Add(new ListItem("Text", "Value"))
And to change text of or value of an item, you can do it like this:
combo1.Items[0].Text = 'new Text';
combo1.Items[0].Value = 'new Value';
There is no class called ListItem in Windows Forms. It only exists in ASP.NET, so you will need to write your own class before using it, the same as @Adam Markowitz did in his answer.
Also check these pages, they may help:
How add an item to a combobox
How to: Add and Remove Items from a Windows Forms ComboBox, ListBox, or CheckedListBox Control
Don't know if this will work for the situation given in the original post (never mind the fact that this is two years later), but this example works for me:
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";
To read your value back out, you'll have to cast the SelectedItem property to a DictionaryEntry object, and you can then evaluate the Key and Value properties of that. For instance:
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);
If anyone is still interested in this, here is a simple and flexible class for a combobox item with a text and a value of any type (very similar to Adam Markowitz's example):
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;
}
}
Using the <T>
is better than declaring the value
as an object
, because with object
you'd then have to keep track of the type you used for each item, and cast it in your code to use it properly.
I've been using it on my projects for quite a while now. It is really handy.
I liked fab's answer but didn't want to use a dictionary for my situation so I substituted a list of tuples.
// 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;
An example using 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();
Better solution here;
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";
Retreive Data
MessageBox.Show(cmbUser.SelectedValue.ToString());
You may use a generic Type:
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;
}
}
Example of using a simple 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);
}
Further to Adam Markowitz's answer, here is a general purpose way of (relatively) simply setting the ItemSource
values of a combobox to be enums
, while showing the 'Description' attribute to the user. (You'd think everyone would want to do this so that it would be a .NET one liner, but it just isn't, and this is the most elegant way I've found).
First, create this simple class for converting any Enum value into a ComboBox item:
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;
}
}
Secondly in your OnLoad
event handler, you need to set the source of your combo box to be a list of ComboEnumItems
based on every Enum
in your Enum
type. This can be achieved with Linq. Then just set the 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";
}
Now the user will select from a list of your user friendly Descriptions
, but what they select will be the enum
value which you can use in code.
To access the user's selection in code, comboBoxUserReadable.SelectedItem
will be the ComboEnumItem
and comboBoxUserReadable.SelectedValue
will be the EMyEnum
.
Class creat:
namespace WindowsFormsApplication1
{
class select
{
public string Text { get; set; }
public string Value { get; set; }
}
}
Form1 Codes:
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);
}
}
}
You can use this code to insert some items into a combo box with text and 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"/>
I had the same problem, what I did was add a new ComboBox
with just the value in the same index then the first one, and then when I change the principal combo the index in the second one change at same time, then I take the value of the second combo and use it.
This is the code:
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;
}
This is how Visual Studio 2013 does it:
Single item:
comboBox1->Items->AddRange(gcnew cli::array< System::Object^ >(1) { L"Combo Item 1" });
Multiple Items:
comboBox1->Items->AddRange(gcnew cli::array< System::Object^ >(3)
{
L"Combo Item 1",
L"Combo Item 2",
L"Combo Item 3"
});
No need to do class overrides or include anything else. And yes the comboBox1->SelectedItem
and comboBox1->SelectedIndex
calls still work.
This is similar to some of the other answers, but is compact and avoids the conversion to dictionary if you already have a list.
Given a ComboBox
"combobox" on a windows form and a class SomeClass
with the string
type property Name
,
List<SomeClass> list = new List<SomeClass>();
combobox.DisplayMember = "Name";
combobox.DataSource = list;
Which means that the SelectedItem is a SomeClass
object from list
, and each item in combobox
will be displayed using its name.
This is a very simple solution for windows forms if all is needed is the final value as a (string). The items' names will be displayed on the Combo Box and the selected value can be easily compared.
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;
and on the event handler get the value (string) of the selected value
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();
精彩评论