给定一个非常简单的设置:ComboBox应由BindingList<string>
填充。显然,SelectedValueChanged
和SelectedIndexChanged
事件非常重要。但他们都表现得很奇怪:
SelectedValueChanged
个事件。为什么有两个事件而不是一个,即使报告的值在这两个事件之间没有变化?同时,即使索引从-1更改为0,也会丢失SelectedIndexChanged
事件。SelectedValueChanged
个事件,即使所选值实际上保持不变。但是没有SelectedIndexChanged
个事件。但这是预期的,因为所选索引在这里没有变化。SelectedValueChanged
个事件。但是,我没有看到SelectedIndexChanged
个事件。SelectedValueChanged
和SelectedIndexChanged
,正如我所料。SelectedValue
为“项目1”,SelectedIndex
为0)。但是现在我没有收到任何Changed事件,无论是值还是索引。SelectecValueChanged
事件(步骤3)。由于我不希望SELECT被打破,请指出我在这里缺少的东西。
请注意(关于@Alex Horlock的答案):在此示例中,ComboBox选择仅受向数据源添加/删除项目的影响。以交互方式更改ComboBox中的选定项目的行为符合预期。
以下是示例Form1的代码(包含ComboBox和三个按钮(添加/删除/状态):
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}]");
}
}
}
答案 0 :(得分:0)
我不确定为什么所有这些事件按此顺序触发,但我认为你想使用selectionChangeCommitted事件来避免这种类型的问题。
答案 1 :(得分:0)
ComboBox的.NET Framework代码维护一个私有标志,用于存储有关已触发的更改事件的信息。只有在找到实现ICurrencyManagerProvider
的数据源时,才会重置此标志。不幸的是,BindingList<T>
没有实现此接口。好消息是BindingSource
确实实现了它。所以我所要做的就是在ComboBox和BindingSource
之间放置BindingList<T>
,如下所示:
BindingSource
从工具箱中删除到表单上。在表单的构造函数中,我替换了
comboBox1.DataSource = new BindingList<string>();
与
bindingSource1.DataSource = new BindingList<string>();
comboBox1.DataSource = bindingSource1;
这就是诀窍。
仍有许多重复和无关的事件被解雇。但是,这个解决方案是在步骤6中触发事件,这曾是原始版本中的显示停止。