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

backgroundworkerは別のスレッドで動作します。その中の呼び出し元のスレッドに属するコントロールを呼び出すことは許可されていません。

RunWorkerCompletedUwe Keimが言ったように、イベントではコントロールに触れるすべてのものを配置する必要があります。

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

最良の方法はLaurentの例です

汚い方法:

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 に答える