C# 关于BindingList作为组合框数据源的争论
给出一个非常简单的设置:一个组合框应该由一个C# 关于BindingList作为组合框数据源的争论,c#,winforms,data-binding,combobox,C#,Winforms,Data Binding,Combobox,给出一个非常简单的设置:一个组合框应该由一个BindingList填充。显然,SelectedValueChanged和selectedindex changed事件非常重要。但他们的行为都很奇怪: 列表最初为空。 在添加第一项时,我收到两个连续的SelectedValueChanged事件。为什么有两个事件而不是一个,即使报告的值在这两个事件之间没有变化?同时,SelectedIndexChanged事件丢失,即使索引刚刚从-1更改为0 添加其他项目。现在,对于添加的每个项目,我都会收到一个S
BindingList
填充。显然,SelectedValueChanged
和selectedindex changed
事件非常重要。但他们的行为都很奇怪:
SelectedValueChanged
事件。为什么有两个事件而不是一个,即使报告的值在这两个事件之间没有变化?同时,SelectedIndexChanged
事件丢失,即使索引刚刚从-1更改为0SelectedValueChanged
事件,即使所选值实际上保持不变。但是,没有选择索引更改的事件。但这是意料之中的,因为此处所选索引没有更改
SelectedValueChanged
事件。但是,我没有看到SelectedIndexChanged
事件SelectedValueChanged
和selectedindex changed
SelectedValue
为“项目1”,而SelectedIndex
为0)。但是现在我没有收到任何更改的事件,无论是值还是索引SelectecValueChanged
事件名称空间绑定测试
{
使用制度;
使用系统组件模型;
使用System.Linq;
使用System.Windows.Forms;
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
comboBox1.DataSource=新绑定列表();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
var dataSource=comboBox1.dataSource作为BindingList;
dataSource?.Add($“Item{dataSource.Count+1}”);
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
var dataSource=comboBox1.dataSource作为BindingList;
如果(数据源?.Count>0)
{
删除(dataSource.Last());
}
}
私有无效按钮3\u单击(对象发送者,事件参数e)
{
WriteLine($“SelectedValue:{comboBox1.SelectedValue}”);
WriteLine($“SelectedIndex:{comboBox1.SelectedIndex}”);
}
私有无效组合框1\u SelectedIndexChanged(对象发送方,事件参数e)
{
var dataSource=comboBox1.dataSource作为BindingList;
WriteLine($“SelectedINDEXChanged:{comboBox1.SelectedIndex}[{dataSource?.Count}]”);
}
private void comboBox1\u SelectedValueChanged(对象发送方,事件参数e)
{
var dataSource=comboBox1.dataSource作为BindingList;
WriteLine($“SelectedVALUEChanged:{comboBox1.SelectedValue}[{dataSource?.Count}]”);
}
}
}
我不确定为什么所有这些事件都会按该顺序触发,但我认为您希望使用selectionChangeCommitted事件来避免此类问题
请参见-()我不确定为什么所有这些事件都会按该顺序触发,但我认为您希望使用selectionChangeCommitted事件来避免此类问题
见-()ComboBox的.NET Framework代码维护一个私有标志,用于存储有关已触发的更改事件的信息。只有在发现数据源实现了
ICurrencyManagerProvider
时,才会重置此标志。不幸的是,BindingList
没有实现此接口。好消息是BindingSource
确实实现了它。所以我所要做的就是在组合框和绑定列表之间放置一个BindingSource
,如下所示:
- 我只是从工具箱中将一个
BindingSource
放到表单上
- 在窗体的构造函数中,我替换了
comboBox1.DataSource = new BindingList<string>();
comboBox1.DataSource=newbindingList();
与
bindingSource1.DataSource=newbindingList();
comboBox1.DataSource=bindingSource1;
这就成功了
仍有许多重复和不相关的事件被激发。但是,此解决方案在步骤6中激发事件,这在原始版本中曾经是显示的止动符。ComboBox的.NET Framework代码维护一个私有标志,存储有关已激发的更改事件的信息。此标志只有在找到时才会重置实现ICurrencyManagerProvider
的数据源。不幸的是,BindingList
没有实现此接口。好消息是BindingSource
确实实现了它。所以我所要做的就是在组合框和BindingList
之间放置一个BindingSource
,如下所示:
- 我只是从工具箱中将一个
BindingSource
放到表单上
- 在
comboBox1.DataSource = new BindingList<string>();
bindingSource1.DataSource = new BindingList<string>();
comboBox1.DataSource = bindingSource1;