Bohn
Bohn

Reputation: 26919

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].Value = "useful Value"

Upvotes: 242

Views: 1022323

Answers (21)

fab
fab

Reputation: 2509

// 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;

Upvotes: 213

FAdao
FAdao

Reputation: 11

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();

Upvotes: 1

Muhammad Ahmad
Muhammad Ahmad

Reputation: 31

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"/>

Upvotes: 1

Orhan Bayram
Orhan Bayram

Reputation: 106

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());

Upvotes: 4

cronynaval
cronynaval

Reputation: 221

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

Upvotes: 22

Bill Pascoe
Bill Pascoe

Reputation: 21

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.

Upvotes: 2

Matheus Rocha
Matheus Rocha

Reputation: 1204

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.

Upvotes: 6

Mert Cingoz
Mert Cingoz

Reputation: 762

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

Upvotes: 54

Esteban Verbel
Esteban Verbel

Reputation: 738

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();

Upvotes: 0

Alex Smith
Alex Smith

Reputation: 1126

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.

Upvotes: 0

Status3543
Status3543

Reputation: 1277

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.

Upvotes: 0

Limitless isa
Limitless isa

Reputation: 3802

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);

        }

    }
}

Upvotes: 1

Miguel
Miguel

Reputation: 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;
}

Upvotes: 0

buhtla
buhtla

Reputation: 2909

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;

Upvotes: 140

Soenhay
Soenhay

Reputation: 4048

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();

Upvotes: 3

Jan Staecker
Jan Staecker

Reputation: 21

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);
    }

Upvotes: 2

Maggie
Maggie

Reputation: 1547

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;

Upvotes: 4

Amr Elgarhy
Amr Elgarhy

Reputation: 68902

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:

Upvotes: 16

Ryan
Ryan

Reputation: 83

//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);

Upvotes: 7

ChuckG
ChuckG

Reputation: 121

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);

Upvotes: 12

Adam Markowitz
Adam Markowitz

Reputation: 13107

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());
}

Upvotes: 420

Related Questions