How do you refresh a combo box item in-place?

11,755

Solution 1

Got it, using Donut's suggestion.

In form class:

private BindingList<PlantComboBoxItem> _plantList;

In loading method:

_plantList = new BindingList<PlantComboBoxItem>(plantItems);
cboPlants.DataSource = _plantList;

In SelectedIndexChanged event:

int selectedIndex = cboPlants.SelectedIndex;
_plantList.ResetItem(selectedIndex);

Thank you!

Solution 2

A dirty hack:

typeof(ComboBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, cboPlants, new object[] { });

Solution 3

Hmm... could you use a BindingList<T>, as described here? That way, you could just modify the item in the underlying collection and have it reflected in the ComboBox without having to add or remove anything from the control.

You'd need to have a collection something like this, containing all your items for the ComboBox:

private BindingList<PlantComboBoxItem> plantComboBoxItems;

Then, at some point (like when the program is starting), bind it to the ComboBox:

cboPlants.DataSource = plantComboBoxItems;

Now, you can just modify the collection directly:

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant();

And changes will be reflected in cboPlants. Is this what you're looking for?

Share:
11,755
Jon Seigel
Author by

Jon Seigel

Ethical hacker and audio mixing &amp; mastering professional. Personal: YouTube Channel | Facebook | @JonSeigel VoluntaryDBA: Blog | YouTube Channel | Facebook | @VoluntaryDBA

Updated on June 08, 2022

Comments

  • Jon Seigel
    Jon Seigel almost 2 years

    The ComboBox Items collection is an ObjectCollection, so of course you can store anything you want in there, but that means you don't get a Text property like you would with, say, a ListViewItem. The ComboBox displays the items by calling ToString() on each item, or using reflection if the DisplayMember property is set.

    My ComboBox is in DropDownList mode. I have a situation where I want to refresh the item text of a single item in the list when it gets selected by the user. The problem is that the ComboBox doesn't re-query for the text at any time besides when it loads up, and I can't figure out how else to do what I want besides removing and re-adding the selected item like so:

    
    PlantComboBoxItem selectedItem = cboPlants.SelectedItem as PlantComboBoxItem;
    
    // ...
    
    cboPlants.BeginUpdate();
    
    int selectedIndex = cboPlants.SelectedIndex;
    cboPlants.Items.RemoveAt(selectedIndex);
    cboPlants.Items.Insert(selectedIndex, selectedItem);
    cboPlants.SelectedIndex = selectedIndex;
    
    cboPlants.EndUpdate();
    

    This code works fine, except for the fact that my SelectedIndex event ends up getting fired twice (once on the original user event, and then again when I re-set the property in this code). In this case, it's not a big deal that the event is fired twice, but it's inefficient, and I hate that. I could rig up a flag so it exits the event the second time, but that's hacking.

    Is there a better way to get this to work?

  • Jon Seigel
    Jon Seigel over 14 years
    As an aside, I wonder why no one thought to include something like a RefreshItem function on the ComboBox.
  • Donut
    Donut over 14 years
    Do you need to call ResetItem()? The item in cboPlants should be changed if you just update it directly (I think?). You can access it in the SelectedIndexChanged event with _plantList[selectedIndex].
  • Jon Seigel
    Jon Seigel over 14 years
    Yes, I do have to call ResetItem(). The control has no idea to refresh the item otherwise (I tried taking out that line and it didn't update the item when I changed it). The item does not get updated automatically even though the underlying data in the PlantComboBoxItem changed. I think the ResetItem() function must be internally implemented as what I was doing before -- manually removing and then adding the item again. Such a PITA.