Initializing a combobox to a blank value might be harder than you think

Combobox troubles again today. No matter how hard I tried to have Comboboxes in my dialog form to initially display blank (SelectedIndex = -1), as soon as the dialog was displayed, the combos would always show the first item in the List that populated it. Despite being set to -1 explicitly. It was driving me nuts.

When created at runtime using a List as DataSource, getting this (empty combos) might be harder than you think

The situation: I had a dialog form that should have a variable number of comboboxes on it, determined at runtime. So the form had an Init method where I dynamically added the comboboxes, and set its DataSource to a List of items (directly, no BindingSource). The form also has a LoadData method, that sets the SelectedIndex of each combo to the actual value from the data, or to -1 of it was unknown or uninitialized at that time. This was to be able to make the combo appear blank instead of preselecting the first item, which was undesired. The caller of the dialog executes Init(), LoadData() and finally ShowDialog().

I was expecting a blank combobox, but it showed the first item in the list preselected. I triple checked that the SelectedIndex was correctly set to -1 at the end of LoadData(), but as soon as the form was displayed, it was 0. What the *** happened there in between and “who” was secretly setting my property!? Lees meer over dit bericht

Advertenties

WinForms ComboBox does not always fire SelectionChangeCommitted

Today I ran into the problem that a ComboBox in my project did not always fire the SelectionChangeCommitted event when I expected it to. To be specific, if a user dropped down the list, used the arrow keys to move to an item, and then TABbed to the next control, the new item would be selected but the event never fired. This was a problem for me, because I relied on this event to filter the items in the next control, depending on the selection made in the first.

Some googling quickly learned that this was a known problem with the ComboBox, although the thread is about the SelectedIndexChanged event, it appears the same error prevents SelectionChangeCommitted from behaving as expected. As user comecme in that thread pointed out, there even was a knowledgebase item including a workaround available from Microsoft. But as he also points out… the workaround does not work.

So I decided to cook up my own solution. This would involve subclassing the Combobox to change the behavior I needed. I had one advantage, I was already using a subclassed ComboBox in all places I needed this behavior, so no Find+Replace was required to replace all standard ComboBoxes with my own.

To this subclassed combobox (named CatalogComboBox) I added the following code:

private CatalogComboItem keepSelection;

protected override void OnEnter(EventArgs e) {
  keepSelection = this.SelectedItem;
  base.OnEnter(e);
}

protected override void OnLeave(EventArgs e) {
  if (this.SelectedItem != keepSelection)
    OnSelectionChangeCommitted(EventArgs.Empty);
  base.OnLeave(e);
}

protected override void OnSelectionChangeCommitted(EventArgs e) {
  base.OnSelectionChangeCommitted(e);
  keepSelection = this.SelectedItem;
}

(I used CatalogComboItem because my combo items where typed as such, but you can always use object.) It’s a not spectacularly elegant or high-tech solution, but it works like a charm.