如何就地刷新combobox项目?

ComboBox Items集合是一个ObjectCollection,所以当然你可以在那里存储任何你想要的东西,但这意味着你不会像使用ListViewItem一样获得Text属性。 ComboBox通过在每个项目上调用ToString()来显示项目,或者如果设置了DisplayMember属性则使用reflection。

我的ComboBox处于DropDownList模式。 我有一种情况,当用户选择它时,我想刷新列表中单个项目的项目文本。 问题是ComboBox除了加载之外不会在任何时候重新查询文本,除了删除和重新添加所选项目之外,我无法弄清楚除了删除和重新添加所选项目之外我还想做什么:

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(); 

这段代码工作正常,除了我的SelectedIndex事件最终被触发两次(一次在原始用户事件上,然后再次在我重新设置此代码中的属性时)。 在这种情况下,事件被触发两次并不是什么大问题,但效率低下,我讨厌这个。 我可以装备一个标志,以便它第二次退出事件,但这是黑客攻击。

有没有更好的方法让这个工作?

肮脏的黑客:

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

嗯……你能使用BindingList ,如下所述? 这样,您可以只修改底层集合中的项目,并将其反映在ComboBox而无需在控件中添加或删除任何内容。

你需要有一个像这样的集合,包含ComboBox所有项目:

 private BindingList plantComboBoxItems; 

然后,在某些时候(比如程序启动时),将它绑定到ComboBox

 cboPlants.DataSource = plantComboBoxItems; 

现在,您可以直接修改集合:

 plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant(); 

而变化将反映在cboPlants 。 这是你在找什么?

知道了,使用Donut的建议。

在表单类中:

 private BindingList _plantList; 

在加载方法:

 _plantList = new BindingList(plantItems); cboPlants.DataSource = _plantList; 

在SelectedIndexChanged事件中:

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

谢谢!