Exception:
Controls created on one thread cannot be parented to a control on a different thread.
This thread explains nicely how to do it on the instance of the class, (uses this keyword) statics don't refer to the instance so I'm out of luck there.
The class where the calling function is not static, and is calling this function like this...
DrawPlane.drawPlane(ref pnl);
Also in the calling class, I used this naughty property to attempt to mitigate illegal cross-threading...
CheckForIllegalCrossThreadCalls = false;
The full class:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Skork.ui {
class DrawPlane {
private static int numX;
private static int numY;
private static BackgroundWorker bg;
static DrawPlane() {
numX = 0;
numY = 0;
bg = new BackgroundWorker();
}
public static void drawPlane(ref Panel plane) {
bg.DoWork += Bg_DoWork;
bg.RunWorkerAsync(plane);
}
private static void Bg_DoWork(object sender, DoWorkEventArgs e) {
Panel plane = new Panel();
if (e.Argument is Panel) {
plane = (Panel) e.Argument;
} else {
throw new Exception("Object is not a panel!!" +
e.Argument.ToString());
}
plane.Controls.Clear();
numX = 0;
numY = 0;
Random rnd = new Random();
Size sz = plane.Size;
Point temp = new Point(0, 0);
const int sizeUnit = 4; // 4 pixels wide
bg.DoWork += Bg_DoWork; // add event
int x = 0;
for (int y = 0; y < sz.Height; y += sizeUnit * sizeUnit) {
temp.X = 0;
numY++;
for (x = 0; x < sz.Width; x += sizeUnit * (sizeUnit / 2)) {
if (x + temp.X < sz.Width) {
PictureBox unit = new PictureBox();
rnd = new Random(rnd.Next());
unit.Size = new Size(sizeUnit * sizeUnit, sizeUnit * sizeUnit);
unit.Location = new Point(x + temp.X, y + temp.Y);
unit.BackColor = Color.FromArgb(255, rnd.Next(255),
rnd.Next(255), rnd.Next(255));
unit.Click += Unit_Click;
plane.Controls.Add(unit);
temp.X += sizeUnit * 2;
temp.Y = 0;
numX++;
} else {
continue;
}
}
}
numX = numX / numY; // determine number of boxes on X-axis
}
private static void Unit_Click(object sender, EventArgs e) {
if (sender is PictureBox) {
PictureBox p = (PictureBox)sender;
MessageBox.Show(p.Location.ToString() + " = Number in x-axis " + numX + " - number in y-axis " + numY);
return;
}
throw new Exception("Not a picturebox for some reason. - " + sender.ToString());
}
}
}