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