I like to populate array "numbers" in a "treeView1" control. All works well if I don't use backgroundWorker control.
If I use backgroundWorker nothing is displayed in the treeView1. It looks like the code is stuck in the foreach loop.
//Step1
private void button1_Click(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false;
backgroundWorker1.RunWorkerAsync();
button1.Enabled = false;
}
//Step2
private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
{
int[] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
foreach (int element in numbers)
{
treeView1.Nodes.Add(element.ToString());
}
button1.Enabled = true;
}
I tried all you suggested below and still doesn't display anything
//Step1
private void button1_Click(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.RunWorkerAsync();
button1.Enabled = false;
}
//Step2
private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
{
this.treeView1.Nodes.Clear();
int[] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
treeView1.BeginUpdate();
foreach (int element in numbers)
{
treeView1.Nodes.Add(element.ToString());
}
treeView1.EndUpdate();
button1.Enabled = true;
treeView1.Refresh();
}
Thanks to Banjamin now all work :)
//Step1
private void button1_Click(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.RunWorkerAsync();
button1.Enabled = false;
}
//Step2
private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
{
this.treeView1.Nodes.Clear();
int[] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
treeView1.Invoke((Action)delegate
{
foreach (int element in numbers)
{
treeView1.Nodes.Add(element.ToString());
}
});
treeView1.EndUpdate();
//button1.Enabled = true;
treeView1.Refresh();
System.Windows.Forms.MessageBox.Show("Completed");
button1.Invoke((Action)delegate { button1.Enabled = true; });
}
If you run your code in the debugger you will get an exception popup giving you more details on what is going wrong:
You should always update your UI from the main (or window) thread of your application. The correct code is:
By using the Invoke method on treeView1 and button1 you ensure the correct thread is used to update the UI.