我认为代码说明清楚
private void ucPerson_Load(object sender, EventArgs e)
{
person = new Person();
BackgroundWorker backgroundBinder = new BackgroundWorker();
backgroundBinder.DoWork += BindComboBoxes;
backgroundBinder.RunWorkerAsync();
}
private void BindComboBoxes(object sender, DoWorkEventArgs e)
{
cmbEducationLevel.DataSource = Program.eService.GetEducationLevels();
cmbNationality.DisplayMember = "Name";
cmbNationality.ValueMember = "NationalityID";
}
我得到错误:
跨线程操作无效:控制从创建它的线程以外的线程访问“cmbNationality”。
我需要做些什么才能让background-worker
的线程访问组合框?
答案 0 :(得分:3)
backgroundworker在另一个线程中工作:不允许调用属于其中调用线程的控件。
正如Uwe Keim所说,你必须在RunWorkerCompleted
事件中放置触及控件的所有内容:
private void ucPerson_Load(object sender, EventArgs e)
{
person = new Person();
BackgroundWorker backgroundBinder = new BackgroundWorker();
backgroundBinder.DoWork += GetData;
backgroundBinder.RunWorkerCompleted += BindComboBoxes;
backgroundBinder.RunWorkerAsync();
}
<<yourReturnType>> source;
private void GetData(object sender, DoWorkEventArgs e)
{
source = Program.eService.GetEducationLevels();
}
private void BindComboBoxes(object sender, RunWorkerCompletedEventArgs e)
{
cmbNationality.DisplayMember = "Name";
cmbNationality.ValueMember = "NationalityID";
cmbNationalty.DataSource = source;
}
答案 1 :(得分:0)
最好的方式是Laurent的例子
肮脏的方式:
cmbEductionLevel.Invoke((MethodInvoker)delegate { mbEducationLevel.DataSource = Program.eService.GetEducationLevels(); });
cmbNationality.Invoke((MethodInvoker)delegate {
cmbNationality.DisplayMember = "Name";
cmbNationality.ValueMember = "NationalityID";
});
答案 2 :(得分:-1)
您应该使用Invoke并传递委托以更新控件。