我想要一个基本的ListBox以及相关的Add和Delete按钮。当且仅当在列表框中有一个选择项时,才启用“删除”按钮,并且“添加”按钮应将一个项目附加到列表框的末尾。
我的第一个尝试是仅创建一个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>();
}
但是,事实证明,随着列表中项目的更改,列表框似乎并没有自动更新。 Here's a related question。
大多数建议都建议每次我更新列表时都只运行listBox1.DataSource = null; this.listBox1.DataSource = this.items;
,但对我而言,这违反了绑定的目的。
另一个答案建议使用ObservableCollection
作为我列表的数据类型,但这没什么不同。
最后,我找到了BindingList
类,它似乎可以满足我的要求。 ListBox会自动反映items
字段的内容。 (如果还有另一种实际上是最佳实践的解决方案,而不是在Internet上粘贴一些不道德的民间传说,请让我知道。)
但是,当我添加到items
的第一项出现在列表框中时,该行被选中。而且我可以看到listBox1.SelectedIndex
从-1变为0。但是,listBox1_SelectedIndexChanged
事件不会触发。因此,“删除”按钮的状态无法正确更新。
(顺便说一句,这种UI模式是极端司空见惯,而关于实现这种简单操作的信息如此之多,似乎是灾难性的。)
答案 0 :(得分:0)
我也遇到了同样的问题。由于这是我遇到的第一个问题,所以也许我的答案可以节省一些时间。
为DataSource
分配一个空的BindingList
并在以后将项目添加到该BindingList
中,就像这样:
private BindingList<MyType> _myList = new BindingList<MyType>();
public MyForm()
{
listBox1.DataSource = _myList;
}
private void LoadData()
{
foreach (MyType item in GetDataFromSomewhere())
{
_myList.Add(item);
}
}
然后添加第一项后,将在ListBox
中选择,而listBox1.SelectedIndex
将为0-但不会触发SelectedIndexChanged
事件。
一种解决方法可能是从ListBox
导出为Juan did,或者只是在添加之前检查BindingList
是否包含任何项目:
bool isFirstItem = (0 == _myList.Count);
_myList.Add(item);
if (isFirstItem)
{
// Your choice: set listBox1.SelectedIndex to -1 and back to 0,
// or call the event handler yourself.
}
答案 1 :(得分:-1)
尝试手动选择最后一个元素,而不要依赖默认行为。这将触发事件。
public partial class Form1 : Form
{
BindingList<string> items = new BindingList<string>();
public Form1()
{
InitializeComponent();
this.listBox1.DataSource = items;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.deleteButton.Enabled = (this.listBox1.SelectedIndex != -1);
}
private void addButton_Click(object sender, EventArgs e)
{
this.items.Add($"item {this.items.Count + 1}");
this.listBox1.SelectedIndex = -1;
this.listBox1.SelectedIndex = this.listBox1.Items.Count - 1;
}
private void deleteButton_Click(object sender, EventArgs e)
{
this.items.RemoveAt(this.listBox1.SelectedIndex);
}
}