Problem with SelectedValue when Sorted is true (ComboBox)

Viewed 721

When setting ComboBox.Sorted to true, ComboBox.SelectedValue returns a different values than the visibly selected value.

Load items and show:

using (ModelContext model = new ModelContext())
{
    cbWorker.ValueMember = "IdWorker";
    cbWorker.DisplayMember = "FullName";

    bindingWorker.DataSource = model.Workers.Select(x => new ItemWorker{
            IdWorker = x.Id,
            FullName = x.FullName
        })
        .ToList();

    cbWorker.DataSource = bindingWorker;
}

private void CbWorker_SelectedValueChanged(object sender, EventArgs e)
{
    object x = cbWorker.SelectedValue;
    if (x!= null) label.Text = x.ToString();
}

If ComboBox.Sorted = false, SelectedValue is OK:

enter image description here

But if ComboBox.Sorted = true, SelectedValue isn't OK:

enter image description here

it is possible to fix it? Similar problem with, for example, CheckedListBox.

1 Answers

Set ComboBox.Sorted to false and sort the bindingWorker.DataSource by the IdWorker property:

cbWorker.Sorted = false;

...

bindingWorker.DataSource = model.Workers.Select(x => new ItemWorker{
            IdWorker = x.Id,
            FullName = x.FullName
        })
        .OrderBy(x => x.IdWorker)
        .ToList();

cbWorker.DataSource = bindingWorker;

cbWorker.ValueMember = "IdWorker";
cbWorker.DisplayMember = "FullName";

Explanation:

There are two problems in your example:

  1. Setting ComboBox.Sorted to true on a data-bound ComboBox
  2. Numeric sorting of ComboBox items using ComboBox.Sorted

Setting ComboBox.Sorted to true on a data-bound ComboBox

From ComboBox.Sorted Property documentation:

Attempting to set the Sorted property on a data-bound control raises an ArgumentException. You must sort the data using the underlying data model.

It is probably not a good idea to set ComboBox.Sorted to true on a data-bound ComboBox. Even if it is not throwing an exception, it may cause unexpected behavior.

Numeric sorting of ComboBox items using ComboBox.Sorted

A simple test can show that if ComboBox.Sorted = true:

  • The items are sorted by the ComboBox.DisplayMember
  • The items are sorted as strings (something like item.ToString())

This means that even if ComboBox.DisplayMember was a numeric type, it would be sorted after calling ToString() on each number, so the items would be sorted alphabetically, not as numbers.

For example, if the numbers 10, 1, 3 would be sorted directly as numeric values, they would be sorted to 1, 3, 10, but if the numbers would be first converted to strings ("10", "1", "3") and than sorted, they would be sorted alphabetically to "1", "10", "3"

Conclusion

If you want to:

  • Sort a data bound ComboBox
  • Sort ComboBox items not alphabetically
  • Sort by a member other than the DisplayMember

You have to sort the items before setting the items as the ComboBox.DataSource and set ComboBox.Sorted to false

Related