当数据源更改时,不会触发ListBox SelectedValueChanged/SelectedIndexChanged [英] ListBox SelectedValueChanged/SelectedIndexChanged not firing when data source changes

查看:82
本文介绍了当数据源更改时,不会触发ListBox SelectedValueChanged/SelectedIndexChanged的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是重现此问题的代码:

 公共局部类Form1:表单{私有只读BindingList< string>列表=新的BindingList< string>();公共Form1(){InitializeComponent();listBox1.DataSource =列表;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);};}} 

我的表单有一个列表框 listBox1 和三个按钮: addButton removeButton logSelectionButton .

如果您按下 addButton (从一个空列表开始),然后按下 removeButton ,最后再次按下 addButton ,都不会 SelectedValueChanged addButton 之前和之后按下 logSelectionButton ,code或 SelectedIndexChanged 也不会在最后一次按下 addButton 时触发.code> 按下,你会看到 SelectedIndexSelectedValue 的值都从 -1 变成了 0,从 null 变成了Item1",并且"Item 1"在列表框中看起来已选中.

这将导致我需要根据所选项目更新的所有其他控件保持禁用状态,直到用户在列表框上手动选择了一项,即使已经选择了第一项.

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

解决方案

似乎您在

由于 ListControl 的派生类(如 ListBox ComboBox 等)在数据绑定模式下将其选择与 Position BindingManagerBase 的>属性,可靠的解决方法(基本上是更通用的抽象解决方案)是处理

I need to keep track of the selected item on a ListBox to update/disable other controls according to the currently selected value.

This is the code to reproduce the issue:

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);
        };
    }
}

My form has a list box listBox1 and three buttons: addButton, removeButton and logSelectionButton.

If you press addButton (starting with an empty list), then removeButton and finally addButton again, neither SelectedValueChanged nor SelectedIndexChanged will fire at the last addButton press, even though if you press logSelectionButton before and after the last addButton press, you'll see that the values of both SelectedIndex and SelectedValue have changed from -1 to 0 and from null to "Item 1" respectively, and that "Item 1" looks selected on the list box.

This would cause any other controls I need to update according to the selected item to stay disabled until the user manually selects an item on the list box, even though the first item is already selected.

I can't think of any workaround. Perhaps also subscribing to my BindingList's ListChanged event to see whether the list is empty or not, but then I don't know if the items in the list box will be updated before or after my event handler fires, which will cause other problems.

解决方案

Seems like you found a bug in ListControl internal handling of the PositionChanged event when data bound (if you turn Exceptions on in VS, you'll see an exception when the first item is added to the empty list).

Since ListControl derived classes like ListBox, ComboBox etc. in data bound mode synchronize their selection with the Position property of the BindingManagerBase, the reliable workaround (and basically a more general abstract solution) is to handle CurrentChanged event of the underlying data source binding manager:

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

这篇关于当数据源更改时,不会触发ListBox SelectedValueChanged/SelectedIndexChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆