Search code examples
c#winformscomboboxselectedvalue

C# Winforms - setting combobox selected value


I want to set name and value pairs for combobox. So I created a class named Item like this:

// Content item for the combo box
private class Item
{
    private readonly string Name;
    private readonly int Value;
    private Item(string _name, int _value)
    {
        Name = _name; Value = _value;
    }
    private override string ToString()
    {
        // Generates the text shown in the combo box
        return Name;
    }
}

And data set like this:

comboBox1.DataSource = null;
comboBox1.Items.Clear();
// For example get from database continentals.
var gets = _connection.Continentals;
comboBox1.Items.Add(new Item("--- Select a continental. ---", 0));
foreach (var get in gets)
{
    comboBox1.Items.Add(new Item(get.name.Length > 40 ? get.name.Substring(0, 37) + "..." : get.name, Convert.ToInt32(get.id)));
}
// It points Africa.
comboBox1.SelectedValue = 3;

Here is the output:

// 1 - Europe
// 2 - Asia
// 3 - Africa
// 4 - North America
// 5 - South America
// 6 - Australia
// 7 - Antartica

In my example The Africa continental must be selected but it is not. And more than that in my edit form, for example this code gets datas from person table:

var a = _connection.persons.SingleOrDefault(x => x.id == Id);

When I code comboBox2.SelectedValue = a.continental, the Africa continental must be selected, but it is not. I did not solve the problem.


Solution

  • As described in the SelectedValue property documentation:

    Property Value
    An object containing the value of the member of the data source specified by the ValueMember property.

    Remarks
    If a property is not specified in ValueMember, SelectedValue returns the results of the ToString method of the object.

    To get the desired behavior, you need to expose Name and Value as public properties of your Item class and utilize the DataSource, ValueMember and DisplayMember properties of the control:

    // Content item for the combo box
    private class Item
    {
        public string Name { get; private set; }
        public int Value { get; private set; }
        private Item(string _name, int _value)
        {
            Name = _name; Value = _value;
        }
    }
    

    and the sample usage:

    // Build a list with items
    var items = new List<Item>();
    // For example get from database continentals.
    var gets = _connection.Continentals;
    items.Add(new Item("--- Select a continental. ---", 0));
    foreach (var get in gets)
    {
        items.Add(new Item(get.name.Length > 40 ? get.name.Substring(0, 37) + "..." : get.name, Convert.ToInt32(get.id)));
    }
    // Bind combobox list to the items
    comboBox1.DisplayMember = "Name"; // will display Name property
    comboBox1.ValueMember = "Value"; // will select Value property
    comboBox1.DataSource = item; // assign list (will populate comboBox1.Items)
    
    // Will select Africa
    comboBox1.SelectedValue = 3;