ComboBox: Adding Text and Value to an Item (no Bin

2019-01-01 12:41发布

问题:

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

回答1:

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


回答2:

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


回答3:

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;


回答4:

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


回答5:

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



回答6:

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


回答7:

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



回答8:

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


回答9:

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;


回答10:

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


回答11:

You can use this code combox add item with text and its value

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

to insert some items into combox with text and value. and here its xaml code for combox



回答12:

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.



回答13:

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


回答14:

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.



回答15:

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


回答16:

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

        }

    }
}


回答17:

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.



回答18:

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.



回答19:

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


回答20:

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