PictureBox PaintEvent with other method
You need to decide what you want to do:
- Draw into the Image or
- draw onto the Control?
Your code is a mix of both, which is why it doesn't work.
Here is how to draw onto the Control
:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawEllipse(Pens.Red, new Rectangle(3, 4, 44, 44));
..
}
Here is how to draw into the Image
of the PictureBox
:
void drawIntoImage()
{
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
{
G.DrawEllipse(Pens.Orange, new Rectangle(13, 14, 44, 44));
..
}
// when done with all drawing you can enforce the display update by calling:
pictureBox1.Refresh();
}
Both ways to draw are persistent. The latter changes to pixels of the Image, the former doesn't.
So if the pixels are drawn into the Image and you zoom, stretch or shift the Image the pixel will go with it. Pixels drawn onto the Top of the PictureBox control won't do that!
Of course for both ways to draw, you can alter all the usual parts like the drawing command, maybe add a FillEllipse
before the DrawEllipse
, the Pens
and Brushes
with their Brush type and Colors
and the dimensions.
PictureBox and Paint Event
Add flag (e.g. f_paint_enabled
) in the beginning of PB_Paint and enable/disable it to control the task.
Executing of picture box paint event handler becomes slower and slower
Do not do pictureBox1.Paint += new PaintEventHandler(Draw);//1 in timer1_Tick. Do it once in your form load. Otherwise it will call Draw() many times per each Paint event and the number of calls will increase.
C# Draw on PictureBox with Graphics.DrawLine() not working on Paint event
You should not create a new Graphics object in the event handler.
You should use the one passed from event
public partial class Form1 : Form
{
Point[] points = new Point[2];
public Form1()
{
InitializeComponent();
points[0] = new Point(50, 50);
points[1] = new Point(100, 100);
}
private void button1_Click(object sender, EventArgs e)
{
DrawCrosses(points, pictureBox1.CreateGraphics());
}
private void DrawCrosses(Point[] points, Graphics g)
{
Pen pen = new Pen(Color.Red)
{
Width = 2
};
foreach (Point p in points)
{
Point pt1 = new Point(p.X, p.Y - 10);
Point pt2 = new Point(p.X, p.Y + 10);
Point pt3 = new Point(p.X - 10, p.Y);
Point pt4 = new Point(p.X + 10, p.Y);
g.DrawLine(pen, pt1, pt2);
g.DrawLine(pen, pt3, pt4);
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
DrawCrosses(points, e.Graphics);
}
}
How to call paint event from a button click event?
This should do the trick:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
}
private void button1_Click(object sender, EventArgs e)
{
using (var g = Graphics.FromImage(pictureBox1.Image))
{
g.DrawEllipse(Pens.Blue, 10, 10, 100, 100);
pictureBox1.Refresh();
}
}
}
call Paint event of picturebox from PageLoad in C# causes an error
You shouldn't read from a database in OnPaint and you shouldn't draw on the screen in OnLoad.
So divide the work: in OnLoad, fetch and store the data. In OnPaint, draw the cached data.
How to call a Paint method from a Click event?
Case One: Drawing onto Controls
:
Provided the Paint
event is actually hooked up and not just a piece of code you have copied, this will do the job:
public void button1_Click(object sender, EventArgs e)
{
CrochetPtrnDesign.Invalidate();
}
Update: since we now know that CrochetPtrnDesign
is the Form
simply write: this.Invalidate();
!
If in doubt about hooking up read this!
Note that creating truely valid PaintEventArgs
should only be done by the system..
Case Two: Drawing into Bitmaps:
To draw into a Bitmap
you also need a valid Graphics
object, but you have to create it yourself:
void DrawStuff(Bitmap bmp)
{
using (Graphics g = Graphics.FromImage(bmp))
{
// draw your stuff
g.DrawRectangle(...);
}
// when done maybe assign it back into a Control..
pictureBox.Image = bmp;
}
Update:
Assigning the bitmap to the pictureBox.Image
will work but runs the risk of leaking the previous image. To avoid this you can use a faile-safe method, maybe like this:
void SetImage(PictureBox pb, Bitmap bmp)
{
if (pb.Image != null)
{
Bitmap tmp = (Bitmap)pb.Image;
pb.Image = null;
tmp.Dispose();
}
pb.Image = bmp;
}
Override paint method doesn't work correctly
The problem is that you override OnPaint method of the form instead of Paint
event of the PictureBox. Form's OnPaint happens, when the form needs repainting, and that's independent of what happens with the PictureBox.
Implement OnPaint event of the PictureBox and then you will not have to create Graphics object manually - simply use one provided in the event arguments.
private void Form1_Load(object sender, EventArgs e)
{
// No need to do that
// pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(10, 10, 20, 20));
}
Edit: (in response to comments)
If you want to update the paintbox periodically, do the following:
- Keep the data required to draw the scene somewhere in the form, possibly as a private field
- Use these data to draw the scene in
Paint
event of thePictureBox
- When you need to update the scene, modify the data accordingly, and then call the
Invalidate
method of the PictureBox. It will cause thePaint
event to fire and the scene will be redrawn.
Remember though, that all calls to UI methods from the threads has to be synchronized to the main UI thread (otherwise they won't work or cause problems).
Related Topics
Find a Private Field With Reflection
How to Prevent And/Or Handle a Stackoverflowexception
Mvc Form Not Able to Post List of Objects
Why Catch and Rethrow an Exception in C#
Dynamically Replace the Contents of a C# Method
Linq-To-Entities Join VS Groupjoin
How to Add a Timer to a C# Console Application
Line Delimited Json Serializing and De-Serializing
Catch Multiple Exceptions At Once
Could Not Establish Trust Relationship For Ssl/Tls Secure Channel - Soap
Converting String to Byte Array in C#
C# Getting the Path of %Appdata%
Best Timer For Using in a Windows Service
What's the Difference Between an Object Initializer and a Constructor
Compare Two List≪T≫ Objects For Equality, Ignoring Order
C# Constructor Execution Order