How do you refresh a combo box item in-place?
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?
Jon Seigel
Ethical hacker and audio mixing & mastering professional. Personal: YouTube Channel | Facebook | @JonSeigel VoluntaryDBA: Blog | YouTube Channel | Facebook | @VoluntaryDBA
Updated on June 08, 2022Comments
-
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 over 14 yearsAs an aside, I wonder why no one thought to include something like a RefreshItem function on the ComboBox.
-
Donut over 14 yearsDo you need to call
ResetItem()
? The item incboPlants
should be changed if you just update it directly (I think?). You can access it in theSelectedIndexChanged
event with_plantList[selectedIndex]
. -
Jon Seigel over 14 yearsYes, 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.