Reputation: 403
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
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
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