WinForm-Controls の更新時に「BeginInvoke」などの面倒を見る必要はないと考えたため、バックグラウンド操作には BackgroundWorker を使用したいと考えています。そうですか?私の知る限り、ProgressChanged および RunWorkerCompleted イベント ハンドラを使用して、WinForms コントロールを直接更新できます。
しかし、私はできませんが、次の例外が発生します:
作成されたスレッド以外のスレッドからアクセスされたコントロール コントロール名
いくつかのコード:
public partial class ConfigurationForm : Form
{
public ConfigurationForm()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
label1.Text = String.Empty;
// [...]
}
private void StartButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
label1.Text = "Converting...";
backgroundWorker1.RunWorkerAsync();
}
}
private void CancelButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
backgroundWorker1.CancelAsync();
}
progressBar1.Dispose();
this.Close();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
// EXCEPTION here, why?
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
Converter c = new Converter();
c.Start(worker, e);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// EXCEPTION in all cases, why?
if (e.Cancelled == true)
{
label1.Text = "Canceled";
}
else if (e.Error != null)
{
label1.Text = "Error: " + e.Error.Message;
}
else
{
label1.Text = "Done!";
}
}
}
これは WinForms アプリケーションではなく、VSTO PowerPoint アドインです。上記のフォームは、ユーザーが PowerPoint のリボン バーのアイコンをクリックすると、次のようにアドインによって作成されます。
//Do I need [STAThread] here? but doesn't seem to work anyway
private void button1_Click(object sender, RibbonControlEventArgs e)
{
ConfigurationForm config = new ConfigurationForm();
config.Show();
}
ここで何が問題なのか教えてもらえますか?