給定一個非常簡單的設置:一個ComboBox應該由BindingList<string>
填充。顯然,SelectedValueChanged
和SelectedIndexChanged
事件是非常重要的。但他們都表現得很奇怪:關於BindingList作爲ComboBox數據源Puzzeled
- 該列表最初是空的。
- 在添加第一項時,我會收到兩個連續的
SelectedValueChanged
事件。爲什麼有兩個事件而不是一個,即使報告的值在這兩個事件之間沒有變化?與此同時,即使索引剛剛從-1更改爲0,SelectedIndexChanged
事件也會丟失。 - 添加其他項目。現在,即使所選值實際保持不變,我也會爲每個添加的項目收到一個單獨的
SelectedValueChanged
事件。但是,沒有SelectedIndexChanged
事件。但這是預期的,因爲選定的指數在這裏不會改變。 - 刪除列表末尾的項目。即使沒有發生實際變化,我仍然會收到
SelectedValueChanged
事件。雖然我沒有看到SelectedIndexChanged
事件。 - 刪除最後一個項目(實際上仍然是選定的項目)。正如我所期望的那樣,現在我得到了兩個,分別是
SelectedValueChanged
和SelectedIndexChanged
。 - 再次添加新項目。現在它變得非常奇怪。該項目被添加,因爲它是列表中唯一被選中的項目。 ComboBox按預期報告(
SelectedValue
爲「Item 1」,SelectedIndex
爲0)。但是現在我沒有收到任何改變的事件,無論是價值還是索引。 - 添加更多項目。我沒有收到有關將項目添加到初始列表(步驟3)的(非預期)事件。
因爲我不希望SELECT被打破,請指出我在這裏失蹤的內容。
請注意(關於@Alex Horlock的答案):在本示例中,組合框選擇僅受到向數據源添加/刪除項目或從數據源刪除項目的影響。交互式更改ComboBox中的選定項目的行爲與預期相同。
下面是樣本Form1的代碼(含組合框和三個按鈕(添加/刪除/狀態):
namespace BindingTest
{
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1.DataSource = new BindingList<string>();
}
private void button1_Click(object sender, EventArgs e)
{
var dataSource = comboBox1.DataSource as BindingList<string>;
dataSource?.Add($"Item {dataSource.Count + 1}");
}
private void button2_Click(object sender, EventArgs e)
{
var dataSource = comboBox1.DataSource as BindingList<string>;
if (dataSource?.Count > 0)
{
dataSource.Remove(dataSource.Last());
}
}
private void button3_Click(object sender, EventArgs e)
{
Console.WriteLine($"SelectedValue: {comboBox1.SelectedValue}");
Console.WriteLine($"SelectedIndex: {comboBox1.SelectedIndex}");
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var dataSource = comboBox1.DataSource as BindingList<string>;
Console.WriteLine($"SelectedINDEXChanged: {comboBox1.SelectedIndex} [{dataSource?.Count}]");
}
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
var dataSource = comboBox1.DataSource as BindingList<string>;
Console.WriteLine($"SelectedVALUEChanged: {comboBox1.SelectedValue} [{dataSource?.Count}]");
}
}
}
事實上,SELECT似乎在這裏被打破。在組合框代碼深處,有一個名爲'selectedValueChangedFired'的私有標誌,當列表變空並向其添加新項目時,該標誌不能正確重置。只有在用戶與ComboBox交互時纔會重置。 – freefall