在C#winforms应用程序中加载包含EntityDataModel数据的组合框时SelectedValueChange事件的意外行为

在C#winforms应用程序中加载包含EntityDataModel数据的组合框时SelectedValueChange事件的意外行为,c#,winforms,entity-framework,C#,Winforms,Entity Framework,我使用Windows Forms C#应用程序在combobox中使用linq to实体加载数据 private void Form1_Load(object sender, EventArgs e) { MyEntityDataModel db = new MyEntityDataModel(); var q = from a in db.Customers orderby a.CustomerID descend

我使用Windows Forms C#应用程序在combobox中使用linq to实体加载数据

        private void Form1_Load(object sender, EventArgs e)
        {
            MyEntityDataModel db = new MyEntityDataModel();
            var q = from a in db.Customers orderby a.CustomerID descending select new { ID = a.CustomerID, Name = a.Name.Trim() };
            comboBox1.DataSource = q.ToList();
            comboBox1.ValueMember = "ID";
            comboBox1.DisplayMember = "Name";
        }
        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            listBox1.Items.Add(comboBox1.SelectedValue.ToString());
        }
运行代码时,在第一次加载数据时,所选值更改为列出的4个客户触发4个事件,但所有事件仅为Customer4触发;其中2个将显示成员加载为完整数据行,而另2个将正确加载选定值

1) 如何防止选定值更改事件显示完整的数据行,并仅在第一个项目中显示选定值?
2) 为什么只为第一个项目(Customer4)触发所有事件?

事件只为所选项目触发,在您的情况下,该项目是第一个项目(Customer4)。事件激发的次数与列表中的项目数无关,但与数据绑定相关的属性分配的数量有关。在您的情况下,当您分配
DataSource
(1)时,然后当您分配
ValueMember
(2次-一次在设置属性之前,一次在属性之后)时,最后当您设置
DisplayMember
(1)时,它将激发,因此总共激发4次

我同意它不是那么智能,但请注意,数据绑定可以在不设置
ValueMember
DisplayMember
的情况下工作,从而产生不同的行为。因此,他们决定在修改任何可能影响属性的时触发该事件

所以没有办法让它只燃烧一次。但是,通过在数据源之前分配
ValueMember
DisplayMember
,可以将其减少为2个调用(我总是将此作为经验法则):

此外,您还应该添加一个检查
SelectedValue
是否为
null
,以避免
NullReferenceException
(这通常很好,因为它不仅在数据绑定场景中会发生):


问题是什么?1)如何防止选定值更改事件显示完整的数据行,并仅在第一个项目中显示选定值?2) 为什么所有事件仅针对第4项触发?如果事件引发3次,则可以。它为列表的第一项提高了3次,第一次设置
DataSource
,第二次设置
ValueMember
成员,第三次设置
DisplayMember
。不清楚您的具体要求是什么,但您可以在设置数据源之前删除处理程序,并在完成设置后再次添加它:
comboBox1.SelectedValueChanged-=new Combox1\u SelectedValueChanged;/*…*/comboBox1.SelectedValueChanged+=新Combox1\u SelectedValueChanged欢迎您,感谢您的好意,Ivan的回答足够好,您可以将其标记为已接受:)太好了。非常感谢你聪明而清晰的回答
comboBox1.ValueMember = "ID";
comboBox1.DisplayMember = "Name";
comboBox1.DataSource = q.ToList();
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
    if (comboBox1.SelectedValue != null)
        listBox1.Items.Add(comboBox1.SelectedValue.ToString());
}