C# 绑定列表更新时未激发ListBox SelectedIndexChanged事件
我想要一个带有相关添加和删除按钮的基本列表框。当且仅当列表框中有选择时,才能启用“删除”按钮,并且“添加”按钮应将项目附加到列表框的末尾 我的第一次尝试是创建一个C# 绑定列表更新时未激发ListBox SelectedIndexChanged事件,c#,winforms,listbox,C#,Winforms,Listbox,我想要一个带有相关添加和删除按钮的基本列表框。当且仅当列表框中有选择时,才能启用“删除”按钮,并且“添加”按钮应将项目附加到列表框的末尾 我的第一次尝试是创建一个列表项字段,如下所示: public partial class Form1 : Form { public Form1 { InitializeComponent(); this.listBox1.DataSource = this.items; } private void
列表项
字段,如下所示:
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>();
}
公共部分类表单1:表单{
公共表格1{
初始化组件();
this.listBox1.DataSource=this.items;
}
私有void addButton\u单击(对象发送者,事件参数e){
this.items.Add(“item{this.items.Count+1}”);
}
私有void delete按钮\单击(对象发送者,事件参数e){
this.items.RemoveAt(this.listBox1.SelectedIndex);
}
私有无效列表框1\u SelectedIndexChanged(对象发送方,事件参数e){
this.deleteButton.enabled=(this.listBox1.SelectedIndex!=-1);
}
列表项=新列表();
}
但是,列表框似乎不会随着列表中的项目的更改而自动更新。关于它
大多数建议只运行listBox1.DataSource=null;this.listBox1.DataSource=this.items代码>每次我更新列表时,但对我来说,这违背了绑定的目的
另一个答案建议对我的列表的数据类型使用ObservableCollection
,但这没有什么不同
最后我找到了BindingList
类,它似乎做了我想做的事情;列表框自动反映项
字段的内容。(如果有另一个解决方案实际上是最佳实践,而不是在互联网上粘贴的某个货物崇拜民间传说,请让我知道。)
但是,当我添加到items
的第一个项目出现在列表框中时,该行变为选中。我可以看到listBox1.SelectedIndex
从-1变为0。但是,listBox1\u SelectedIndexChanged
事件不会触发。因此,“删除”按钮的状态无法正确更新
(顺便说一句,这种UI模式非常常见,而且在实现这样一个简单的东西时,有太多相互冲突的信息,这似乎是灾难性的。)尝试手动选择最后一个元素,而不是依赖默认行为。这将触发事件
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);
}
}
公共部分类表单1:表单
{
BindingList项=新建BindingList();
公共表格1()
{
初始化组件();
this.listBox1.DataSource=项目;
}
私有无效列表框1\u SelectedIndexChanged(对象发送方,事件参数e)
{
this.deleteButton.Enabled=(this.listBox1.SelectedIndex!=-1);
}
私有void addButton\u单击(对象发送者,事件参数e)
{
this.items.Add($“item{this.items.Count+1}”);
this.listBox1.SelectedIndex=-1;
this.listBox1.SelectedIndex=this.listBox1.Items.Count-1;
}
私有void delete按钮\单击(对象发送者,事件参数e)
{
this.items.RemoveAt(this.listBox1.SelectedIndex);
}
}
我也遇到了同样的问题。因为这是我遇到的第一个问题,也许我的回答会为别人节省一些时间
当DataSource
被分配一个空的BindingList
时,随后将向该BindingList
添加项,如下所示:
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>();
}
private BindingList\u myList=new BindingList();
公共MyForm()
{
listBox1.DataSource=\u myList;
}
私有void LoadData()
{
foreach(GetDataFromSomewhere()中的MyType项)
{
_myList.Add(项目);
}
}
然后在添加第一个项目后,将在列表框中选择该项目,并且列表框1.SelectedIndex
将为0-但不会触发SelectedIndexChanged
事件
看起来这可能是列表框
中的一个错误
解决方法可以是从ListBox
as派生,或者在添加之前只检查BindingList
是否包含任何项:
bool isFirstItem=(0==\u myList.Count);
_myList.Add(项目);
如果(isFirstItem)
{
//您的选择:将listBox1.SelectedIndex设置为-1并返回0,
//或者自己调用事件处理程序。
}
如果我向构造函数中的this.items
添加单个项,则SelectedIndexChanged
回调将触发两次。我赢不了。不,这个解决方案不起作用。一旦我添加到this.items
,则SelectedIndex
设置为0。如果我再次将其设置为0,则不会触发任何事件。您是对的。通过将索引设置为-1,然后设置最后一项的索引,我可以让它工作。请参阅我的编辑。这感觉像一个黑客,但我想不出另一种方式。编辑:你已经试过了,什么方法不起作用?这件事对我很有利