Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 绑定列表更新时未激发ListBox SelectedIndexChanged事件_C#_Winforms_Listbox - Fatal编程技术网

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,然后设置最后一项的索引,我可以让它工作。请参阅我的编辑。这感觉像一个黑客,但我想不出另一种方式。编辑:你已经试过了,什么方法不起作用?这件事对我很有利