Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ComboBox.SelectedValue is not Working

I have a WinForms application. I've populated my ComboBox with the following code:

cboGridSize.Items.Clear();
for (int i = 2; i <= 12; i++)
    cboGridSize.Items.Add(new KeyValuePair<string,int>(i.ToString(), i));
cboGridSize.SelectedValue = 4;

However, the last line has absolutely no effect. The ComboBox appears with no items selected.

So I was doing some debugging and noticed some odd things. The following image is from the watch window after setting cboGridSize.SelectedIndex to 0.

Watch Window http://www.softcircuits.com/Client/debugwin.jpg

Even though the SelectedItem property contains exactly what I would expect, SelectedValue is still null. Although the documentation for SelectedValue is pathetic, I understood it would contain the value of the selected item (SelectedItem). Instead, the two properties seem completely unrelated. Can anyone see what I have wrong?

As you can see, I have the ValueMember property set. And the DropDownStyle property is set to DropDownList.


EDIT:

Once Nikolay Khil set me straight on the issue here (why the docs for SelectedValue don't do that escapes me), I decided to simply write my own code to accomplish the same task. I'm posting it here in case anyone is interested.

static class ComboBoxHelper
{
    public static void LookupAndSetValue(this ComboBox combobox, object value)
    {
        if (combobox.Items.Count > 0)
        {
            for (int i = 0; i < combobox.Items.Count; i++)
            {
                object item = combobox.Items[i];
                object thisValue = item.GetType().GetProperty(combobox.ValueMember).GetValue(item);
                if (thisValue != null && thisValue.Equals(value))
                {
                    combobox.SelectedIndex = i;
                    return;
                }
            }
            // Select first item if requested item was not found
            combobox.SelectedIndex = 0;
        }
    }
}

This is implemented as an extension method so I simply change my original code as follows:

cboGridSize.Items.Clear();
for (int i = 2; i <= 12; i++)
    cboGridSize.Items.Add(new KeyValuePair<string,int>(i.ToString(), i));
cboGridSize.LookupAndSetValue(4);
like image 222
Jonathan Wood Avatar asked Oct 14 '12 15:10

Jonathan Wood


2 Answers

This does not answer the OP however...the ComboBox SelectedValue must be an integer type.

If you have a short or byte var that holds the value that will set the SelectedValue, it won't work - you will have null/nothing value.

Use an integer.

like image 156
Nathan Evans Avatar answered Nov 12 '22 18:11

Nathan Evans


Both ValueMember and DisplayMember properties are used only if DataSource property is defined.

So, you should re-write your code as follows:

private readonly BindingList<KeyValuePair<string, int>> m_items =
    new BindingList<KeyValuePair<string, int>>();

public YourForm()
{
    InitializeComponent();

    cboGridSize.DisplayMember = "Key";
    cboGridSize.ValueMember = "Value";
    cboGridSize.DataSource = m_items;

    for (int i = 2; i <= 12; i++)
        m_items.Add(new KeyValuePair<string,int>(i.ToString(), i));

    cboGridSize.SelectedValue = 4;
}

Links:

  • BindingList class
  • ObservableCollection class
  • INotifyCollectionChanged Interface
like image 45
Nikolay Khil Avatar answered Nov 12 '22 18:11

Nikolay Khil