3

I have a databound combobox:

using(DataContext db = new DataContext())
{
    var ds = db.Managers.Select(q=> new { q.ManagerName, q.ManagerID});

    cmbbx_Managers.BindingContext = new BindingContext();
    cmbbx_Managers.DataSource = ds;
    cmbbx_Managers.DisplayMember = "ManagerName";
    cmbbx_Managers.ValueMember = "ManagerID";
}

When the form loads neither item is selected, but when the user chooses an item it cannot be deselected. I tried to add cmbbx_Managers.items.Insert(0, "none"), but it does not solve the problem, because it is impossible to add a new item to the databound combobox.

How do I allow a user to deselect a combobox item?

koryakinp
  • 3,989
  • 6
  • 26
  • 56

3 Answers3

6

The way you "deselect" an item in a drop-down ComboBox is by selecting a different item.

There is no "deselect" option for a ComboBox—something always has to be selected. If you want to simulate the behavior where nothing is selected, you'll need to add a <none> item (or equivalent) to the ComboBox. The user can then select this option when they want to "deselect".

It is poor design that, by default, a ComboBox appears without any item selected, since the user can never recreate that state. You should never allow this to happen. In the control's (or parent form's) initializer, always set the ComboBox to a default value.

If you really need a widget that allows clearing the current selection, then you should use a ListView or ListBox control instead.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
4

To add an item to your databound ComboBox, you need to add your item to your list which is being bound to your ComboBox.

var managers = managerRepository.GetAll();

managers.Insert(0, new Manager() { ManagerID = 0, ManagerName = "(None)");

managersComboBox.DisplayMember = "ManagerName";
managersComboBox.ValueMember = "ManagerID";
managersComboBox.DataSource = managers;

So, to deselect, you now simply need to set the ComboBox.SelectedIndex = 0, or else, use the BindingSource.CurrencyManager.

Also, one needs to set the DataSource property in last line per this precision brought to us by @RamonAroujo from his comment. I updated my answer accordingly.

Will Marcouiller
  • 23,773
  • 22
  • 96
  • 162
  • Please always set the DataSource property at the end. Please refer to @Visitor's exaplanation here: http://stackoverflow.com/questions/9521980/combobox-valuemember-and-displaymember – Ramon Araujo Feb 23 '17 at 02:30
  • @RamonAraujo, thanks for this information. I wasn't aware of that. Following the precisions in comment of the answer you point out, it totally makes sense to set the data source in last line. – Will Marcouiller Apr 13 '17 at 13:25
  • After MANY tries to avoid doing it this way, creating workarounds to force the application to accept `.SelectedIndex = -1` without flaws, and failing to accomplish that in all possible scenarios, **I can finally admit that this is the best/simplest way to achieve that behavior**. The other way around is really poor design *as explained by Cody in his answer below*. No to mention that one would end up with more code trying to fix issues caused by it. – 41686d6564 stands w. Palestine Nov 12 '17 at 18:41
3

To deselect an item suppose the user presses the Esc key, you could subscribe to the comboxBox KeyDown event and set selected index to none.

private void cmbbx_Managers_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.Escape && !this.cmbbx_Managers.DroppedDown)
  {
    this.cmbbx_Managers.SelectedIndex = -1;
  }
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225