1

我认为代码很清楚

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的线程能够访问组合框?

4

3 回答 3

3

后台工作人员在另一个线程中工作:您不允许调用属于其中的调用线程的控件。

正如 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;
}
于 2013-02-06T13:02:51.310 回答
0

最好的方法是洛朗的例子

肮脏的方式:

cmbEductionLevel.Invoke((MethodInvoker)delegate { mbEducationLevel.DataSource = Program.eService.GetEducationLevels(); });

cmbNationality.Invoke((MethodInvoker)delegate { 
     cmbNationality.DisplayMember = "Name";
     cmbNationality.ValueMember = "NationalityID"; 
});
于 2013-02-06T13:04:04.280 回答
-1

您应该使用 Invoke 并传递委托以更新控件。

于 2013-02-06T12:59:47.403 回答