Search code examples
c#multithreadingsystem.drawing

painting on a pictureBox from another thread


im having some problems... code is below:

delegate void SetCanvasDelegate(PictureBox canvas);
        public void SetCanvas(PictureBox canvas)
        {
            if (this.canvas.InvokeRequired)
                this.canvas.Invoke(new SetCanvasDelegate(SetCanvas), new object[] { canvas });
            else
                this.canvas = canvas;
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                PictureBox canvas = new PictureBox();
                Graphics g = Graphics.FromHwnd(canvas.Handle);

                RadarElement player = new RadarElement(new Point(150, 150), RadarElementType.Player);

                List<Enemy> enemies = new List<Enemy>();
                ores.Add(new Enemy(new Point(100, 100)));

                g.DrawLine(new Pen(Color.Black), new Point(0, 0), new Point(100, 100));

                if (trackEnemies.Checked)
                    foreach (Enemy e in enemies)
                        g.DrawImage(Image.FromFile("enemy.png"), e.Position);

                SetCanvas(canvas);

                Thread.Sleep(500);
            }
        }

this.canvas is the PictureBox in my Form1.

All of this is within my Form1 class... but the pictureBox in my form is not updated to show enemy.png as above in the code. What is wrong and how do i correct it?


Solution

  • Looks like you're trying to replace the PictureBox of your form with one that's being created within your bw_DoWork method. This won't work the way you expect it to. You need to do your painting on an image object and then stick that painted image into your form's picturebox. If it still doesn't show, use Invalidate as Daren Thomas suggested.

    You probably need to do something along the lines of

    Bitmap canvas = new Bitmap(width, height);
    using(Graphics g = Graphics.FromImage(canvas))
    {
    // paint here
    }
    SetCanvas(canvas);
    

    and then modify your SetCanvas method accordingly to accept an Image instead of a PictureBox.