Jon*_*gel 5 .net c# vb.net combobox winforms
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();
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,除了我的SelectedIndex事件最终被触发两次(一次在原始用户事件上,然后再次在我重新设置此代码中的属性时).在这种情况下,事件被触发两次并不是什么大问题,但它效率低下,我讨厌这个.我可以装备一个标志,以便它第二次退出事件,但那是黑客攻击.
有没有更好的方法让这个工作?
肮脏的黑客:
typeof(ComboBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, cboPlants, new object[] { });
Run Code Online (Sandbox Code Playgroud)
明白了,按照 Donut 的建议。
在表单类中:
private BindingList<PlantComboBoxItem> _plantList;
Run Code Online (Sandbox Code Playgroud)
在加载方法中:
_plantList = new BindingList<PlantComboBoxItem>(plantItems);
cboPlants.DataSource = _plantList;
Run Code Online (Sandbox Code Playgroud)
在 SelectedIndexChanged 事件中:
int selectedIndex = cboPlants.SelectedIndex;
_plantList.ResetItem(selectedIndex);
Run Code Online (Sandbox Code Playgroud)
谢谢你!