Picturebox Paintevent With Other Method

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:

  1. Keep the data required to draw the scene somewhere in the form, possibly as a private field
  2. Use these data to draw the scene in Paint event of the PictureBox
  3. When you need to update the scene, modify the data accordingly, and then call the Invalidate method of the PictureBox. It will cause the Paint 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



Leave a reply



Submit