如何在适当的位置刷新组合框项目?

时间:2009-09-17 17:33:29

标签: c# .net vb.net winforms combobox

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

我的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事件最终被触发两次(一次在原始用户事件上,然后在我重新设置此代码中的属性时)。在这种情况下,事件被触发两次并不是什么大问题,但效率低下,我讨厌这个。我可以装备一个标志,以便它第二次退出事件,但那是黑客攻击。

有没有更好的方法让它发挥作用?

3 个答案:

答案 0 :(得分:8)

肮脏的黑客:

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

答案 1 :(得分:4)

嗯......您可以使用BindingList<T>,如here所述吗?这样,您只需修改基础集合中的项目,并将其反映在ComboBox中,而无需在控件中添加或删除任何内容。

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

private BindingList<PlantComboBoxItem> plantComboBoxItems;

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

cboPlants.DataSource = plantComboBoxItems;

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

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant();

更改将反映在cboPlants中。这是你在找什么?

答案 2 :(得分:2)

根据Donut的建议得到它。

在表单类中:

private BindingList<PlantComboBoxItem> _plantList;

在加载方法中:

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

在SelectedIndexChanged事件中:

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

谢谢!