【发布时间】:2018-07-02 12:47:53
【问题描述】:
我想要一个带有关联的添加和删除按钮的基本列表框。当且仅当 ListBox 中有一个选择时,Delete 按钮才会启用,并且 Add 按钮应该将一个项目附加到 ListBox 的末尾。
我的第一次尝试是创建一个List<string> items 字段,如下所示:
public partial class Form1 : Form {
public Form1 {
InitializeComponent();
this.listBox1.DataSource = this.items;
}
private void addButton_Click(object sender, EventArgs e) {
this.items.Add("item {this.items.Count + 1}");
}
private void deleteButton_Click(object sender, EventArgs e) {
this.items.RemoveAt(this.listBox1.SelectedIndex);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) {
this.deleteButton.enabled = (this.listBox1.SelectedIndex != -1);
}
List<string> items = new List<string>();
}
但是,事实证明,ListBox 似乎不会随着列表中的项目的变化而自动更新。 Here's a related question 关于它。
大多数建议建议我每次更新列表时只运行listBox1.DataSource = null; this.listBox1.DataSource = this.items;,但这对我来说违背了绑定的目的。
另一个答案建议使用ObservableCollection 作为我列表的数据类型,但这并没有什么不同。
最后我找到了BindingList 类,它似乎做了我想做的事; ListBox 会自动反映items 字段的内容。 (如果有其他解决方案实际上是最佳实践,而不是互联网上粘贴的一些货物崇拜民间传说,请告诉我。)
但是,当我添加到 items 的第一项出现在 ListBox 中时,该行将变为选中状态。我可以看到listBox1.SelectedIndex 从 -1 变为 0。但是,listBox1_SelectedIndexChanged 事件不会触发。因此,删除按钮的状态不会正确更新。
(顺便说一句,这种 UI 模式非常司空见惯,而且在实现如此简单的事情上存在如此多相互矛盾的信息似乎是灾难性的。)
【问题讨论】:
-
如果我在构造函数中向
this.items添加一个项目,SelectedIndexChanged回调会触发两次。我赢不了。