【问题标题】:ListBox.SelectedIndexChanged not firing on first occasion [duplicate]ListBox.SelectedIndexChanged 第一次没有触发[重复]
【发布时间】:2017-11-28 14:36:45
【问题描述】:

我有一个 ListBox 绑定到一个默认为空的 BindingList。
当所选索引发生更改时,它应该使用来自所选对象的数据更新其他控件。
问题是 SelectedIndexChanged 事件未在第一个条目上触发(索引从 -1 变为 0)。
但是,当我再次单击第一个条目(尽管在这种情况下索引没有改变)以及添加更多条目时,它确实会触发。
我检查了属性 myListBox.SelectedIndex ,它实际上从 -1 更改为 0,但由于某种原因没有调用事件处理程序。 有谁知道它为什么这样做以及如何解决它?

这是我的代码:

public partial class main : Form
{
    // The class of objects in my BindingList
    [Serializable]
    public class DisplayDefinition : INotifyPropertyChanged
    {
        private string _name;
        private int _width, _height, _posx, _posy;

        public string Name { get { return _name; } set { _name = value; NotifyPropertyChanged("Name"); } }
        public int Width { get { return _width; } set { _width = value; NotifyPropertyChanged("Width"); } }
        public int Height { get { return _height; } set { _height = value; NotifyPropertyChanged("Height"); } }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string s)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(s));
        }
    }

    // Defining the BindingList 
    BindingList<DisplayDefinition> displaydefinitions = new BindingList<DisplayDefinition>();

    // Binding the list to my listbox 
    public main()
    {
        InitializeComponent();
        listDisplays.DataSource = displaydefinitions;
        listDisplays.DisplayMember = "Name";
    }

    // Button adding a new object to the list
    private void btnNewDisplay_Click(object sender, EventArgs e)
    {
        DisplayDefinition d = new DisplayDefinition();
        displaydefinitions.Add(d);
        listDisplays.SelectedItem = d;
    }

    private void listDisplays_SelectedIndexChanged(object sender, EventArgs e)
    {
        DisplayDefinition d = (DisplayDefinition)listDisplays.SelectedItem;
        // Do something with "d" ...
    }
}

【问题讨论】:

  • 不要只描述问题。添加相关代码以重现您的问题
  • 刚刚添加了代码。不要认为它真的很重要(特别是因为它只影响第一个条目),但我想你永远无法确定。
  • 我确认问题中提到的行为。我实际上可以在将ListBox 绑定到数据源时重现该问题,但在手动填充ListBox不能。在第一种情况 (使用数据源) 中,SelectedIndex 属性确实从 -1 变为 0,但 SelectedIndexChanged 事件不会触发。
  • 按设计(或至少,这是现在的预期行为,因为微软不会在这个后期更改 Winforms)。见标记重复。 SelectedIndex 属性在某些条件下显式返回 -1,因此基础字段并没有真正改变。因此,它不会引发属性更改事件。可以说,当数据“合成”的属性值依赖于更改时,它应该......在类似情况下显式引发事件是常见的做法。但它在 Stack Overflow 上有详细记录,但事实并非如此。不用再问了。

标签: c# winforms listbox selectedindexchanged


【解决方案1】:

问题:

此行为仅在将ListBox 与数据源一起使用时发生,而在手动填充ListBox 时不会发生。

原因:

将第一项添加到数据源时,默认选择第一项不会触发SelectedIndexChanged 事件(不知道为什么!) 这似乎是一个错误ListBox,这使得设置 SelectedItemSelectedIndex 属性毫无用处。

解决方案(更像是一种解决方法)

您可以在设置实际的SelectedIndex/SelectedItem 之前将SelectedIndex 属性更改为临时索引(-1),以触发SelectedIndexChanged 事件。

应该可以使用以下方法:

// Button adding a new object to the list
private void btnNewDisplay_Click(object sender, EventArgs e)
{
    DisplayDefinition d = new DisplayDefinition();
    d.Name = "SomeName";
    displaydefinitions.Add(d);
    listDisplays.SelectedIndex = -1;
    listDisplays.SelectedItem = d;
}

private void listDisplays_SelectedIndexChanged(object sender, EventArgs e)
{
    if (listDisplays.SelectedIndex == -1) return;
    DisplayDefinition d = (DisplayDefinition)listDisplays.SelectedItem;
    // Do something with "d" ...
    Console.WriteLine(d.Name);
}

希望有帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2020-08-03
    相关资源
    最近更新 更多