Saku
Saku

Reputation: 403

How to begin draw in one event and continue in another?

I am using Visual Studio 2013 to write a Windows Forms C# application. I want to draw game board on Form1_Load and draw pawns on button click. I have written two methods: InitDraw() and Draw(). When both method are in Form1_Load() or button1_Click() it's OK, but if InitDraw() is in Form1_Load() and Draw() is in button1_Click() - it draws only if I press Alt or move windows out of screen and move back to screen. I added Invalidate() but this does not help.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Bitmap drawBitmap;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitDraw();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Draw();
        }

        private void InitDraw()
        {
            drawBitmap = new Bitmap(500, 500);
            pictureBox1.Image = drawBitmap;
        }

        private void Draw()
        {
            Graphics g = Graphics.FromImage(pictureBox1.Image);
            Pen myPen = new Pen(Color.Black);
            g.DrawLine(myPen, 0, 0, 100, 100);
            myPen.Dispose();
            g.Dispose();
            Invalidate();
        }
    }
}

Upvotes: 1

Views: 289

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112712

You must draw in the Paint event of the picture box. Windows might trigger the Paint event at any moment, e.g. if a window in front of it is removed or the form containing the picturebox is moved.

What you draw on the screen is volatile; therefore, let Windows decide when to (re-)draw. You can also trigger redrawing with

picturebox1.Invalidate();

or

picturebox1.Refresh();

Difference: Invalidate waits until the window is idle. Refresh draws immediately.

If you only draw in Form_Load or Button_Click, your drawing might get lost, when windows triggers a paint on its own. Try calling picturebox1.Invalidate in these events instead.

Upvotes: 0

Blindy
Blindy

Reputation: 67477

Nobody's stopping you from drawing wherever you want, the thing to remember is to do it on a bitmap image instead of trying to force it to screen. By this I mean you need to create your own Bitmap object, and any draw functions you call you call them on this.

To actually get this to show on screen, call the Invalidate function on the host control -- not a PictureBox by the way. Something lightweight like a panel will do. And in that control's Paint event simply draw your image.

You were sort of close, but you calling Invalidate on the form, besides the fact that it's horribly inefficient to redraw everything when you know exactly what needs to be redrawn, simply won't do anything. You don't rely on the Paint event, but on the intrinsic binding a PictureBox has with a Bitmap -- Bitmap who's handle you never change. As far as the PictureBox is concerned, everything is the same so it won't actually paint itself again. When you actually force it to paint itself by dragging the window outside the screen bounds and then back in it will read the bitmap and draw what you expect.

Upvotes: 1

Related Questions