列表框SelectedValueChanged/SelectedIndexChanged在数据源更改时不触发

Jua*_*uan 5 c# listbox winforms .net-4.5

我需要跟踪ListBox上的所选项目,以根据当前选择的值更新/禁用其他控件.

这是重现问题的代码:

public partial class Form1 : Form
{
    private readonly BindingList<string> List = new BindingList<string>();

    public Form1()
    {
        InitializeComponent();
        listBox1.DataSource = List;

        listBox1.SelectedValueChanged += (s, e) => System.Diagnostics.Debug.WriteLine("VALUE");
        listBox1.SelectedIndexChanged += (s, e) => System.Diagnostics.Debug.WriteLine("INDEX");

        addButton.Click += (s, e) => List.Add("Item " + (List.Count + 1));
        removeButton.Click += (s, e) => List.RemoveAt(List.Count - 1);

        logSelectionButton.Click += (s, e) =>
        {
            System.Diagnostics.Debug.WriteLine("Selected Index: " + listBox1.SelectedIndex);
            System.Diagnostics.Debug.WriteLine("Selected Value: " + listBox1.SelectedValue);
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

我的窗体有一个列表框listBox1和三个按钮:addButton,removeButtonlogSelectionButton.

如果按addButton(带一个空表开始),然后removeButton最后addButton一次,既不SelectedValueChanged也没有SelectedIndexChanged将火在最后一addButton按,即使如果按logSelectionButton前最后经过addButton压榨,你会发现两者的值SelectedIndexSelectedValue已经从变化分别为-1到0和从null"项目1",并且在列表框上看起来选择了"项目1".

这将导致我需要根据所选项目更新任何其他控件以保持禁用状态,直到用户手动选择列表框中的项目为止,即使第一项已被选中.

我想不出任何解决方法.也许还订阅我的BindingList ListChanged事件以查看列表是否为空,但后来我不知道列表框中的项是否会在事件处理程序触发之前或之后更新,这将导致其他问题.

Iva*_*oev 4

似乎您在数据绑定时发现了事件ListControl的内部处理中的错误PositionChanged(如果您在 VS 中打开异常,则当第一个项目添加到空列表时您会看到异常)。

由于ListControl派生类(如ListBoxComboBox)在数据绑定模式下将其选择与Position的属性同步BindingManagerBase,因此可靠的解决方法(基本上是更通用的抽象解决方案)是处理CurrentChanged底层数据源绑定管理器的事件:

listBox1.BindingContext[List].CurrentChanged += (s, e) =>
    System.Diagnostics.Debug.WriteLine("CURRENT");
Run Code Online (Sandbox Code Playgroud)