ListBox SelectedValueChanged / SelectedIndexChanged does not work when changing data source

I need to track the selected item in a ListBox to update / disable other controls according to the current selected value.

This is the code to reproduce the problem:

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

In my form has a list box listBox1and three buttons: addButton, removeButtonand logSelectionButton.

addButton ( ), removeButton , , addButton , SelectedValueChanged, SelectedIndexChanged addButton, logSelectionButton addButton , , SelectedIndex, SelectedValue -1 0 null "Item 1" , " 1" .

, , , , , .

. , BindingList ListChanged, , , , , .

+4
2

, ListControl PositionChanged, ( VS , ).

ListControl , ListBox, ComboBox .. Position BindingManagerBase, ( ) CurrentChanged :

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

, , , . ListBox , SelectedIndex, , , :

public class ListBoxThatWorks : ListBox
{
    private int LatestIndex = -1;
    private object LatestValue = null;

    public EqualityComparer<object> ValueComparer { get; set; }

    public override int SelectedIndex
    {
        get { return base.SelectedIndex; }
        set { SetSelectedIndex(value); }
    }

    private void NotifyIndexChanged()
    {
        if (base.SelectedIndex != LatestIndex)
        {
            LatestIndex = base.SelectedIndex;
            base.OnSelectedIndexChanged(EventArgs.Empty);
        }
    }

    private void NotifyValueChanged()
    {
        if (!(ValueComparer ?? EqualityComparer<object>.Default).Equals(LatestValue, base.SelectedValue))
        {
            LatestValue = base.SelectedValue;
            base.OnSelectedValueChanged(EventArgs.Empty);
        }
    }

    private void SetSelectedIndex(int value)
    {
        base.SelectedIndex = value;
        NotifyIndexChanged();
        NotifyValueChanged();
    }
}
0

Source: https://habr.com/ru/post/1670352/


All Articles