Drawing Graphics not working on Form load event - c#

private void DrawIt()
{
System.Drawing.Graphics graphics = this.CreateGraphics();
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(
50, 50, 150, 150);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
private void Form1_Load(object sender, EventArgs e)
{
DrawIt();
}
private void button1_Click(object sender, EventArgs e)
{
DrawIt();
}
when putting the 'DrawIt' method in a button event it works, but in a form load event it doesn't, why?

Change Load event to Paint.
If you want redraw your form use this.Refresh();
When you are in Paint method use:
private void mForm_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillEllipse(...);
}

The Load event is run before the Form is drawn. So anything you draw is overwritten by the Form.
Call your DrawIt method from an event which fires after the Form has loaded.

You need to an event to trigger DrawIt(). You can use a panel or sth else. Then write an OnClik event. Your drawing will start after a click.

if vb6 just add call to your sub or function in Form_Activate

Instead of using Form_Load event use Form_Shown event. That should work.

Related

How can i refresh pictureBox by button?

I have a pictureBox and a button on my form. Button is just refreshing pictureBox. When pictureBox is refreshing it’s drawing line at the pictureBox.
private void button_Click(object sender, EventArgs e)
{
pictureBox.Refresh();
}
And i set OnPaint event for my PictureBox, so when my pictureBox is redrawing its call this method:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//logic for drawing line
//its not so important, cause even if i put messagebox.show, result is the same.
}
I spend whole day to figure out why after pressing the button, line is not appear at the picture box. Turns out that program do like that:
1) button_click -> 2)pictureBox_Paint -> 3) button_click (again!!)
How its even possible? What should i do to just implement logic:
1) button_click -> 2)pictureBox_Paint

How can I call this event from other function?

How can I call this event private void panel1_Paint(object sender, PaintEventArgs e){.....} from like button click function or something?
I've tried panel1.Paint += new PaintEventHandler(panel1_Paint); and couple more but they did not seem to work.
try this:
private void Button1_Click(object sender, EventArgs e){
panel1.Invalidate();
}
the Invalidate() Method force the control to repaint.
You need to use it as simple function:
...your_code...; panel1_Paint(null, null); ...your_code...

Override paint method doesn't work correctly

I am trying to draw a rectangle on PictureBox without using Paint event of picturebox,So i override the Onpaint method :
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = pictureBox1.CreateGraphics();
Pen bPen=new Pen(Color.Blue,3);
dc.DrawRectangle(bPen,0,0,50,50);
}
}
But the rectangle doesn't appear in first time ,but when i change the size of form using mouse my rectangle is appeared why ?!!!
I understand that you do not want to use the Paint event of the PictureBox. Your code wouldn't work since the form gets rendered before its containing elements.
I offer you a solution: draw on a bitmap and then insert that bitmap into the PictureBox through its Image public member.
private void loadDrawing(){
Bitmap map = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
var graph = Graphics.FromImage(map);
graph.DrawRectangle(new Pen(Color.Blue, 3), 0, 0, 50, 50);
pictureBox1.Image = map;
}
Let's say you want to make the Rectangle to show up upon load:
private void Form1_Load(object sender, EventArgs e)
{
loadDrawing();
}
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 the PictureBox
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).
You are overriding the paint method of the form, while you paint the PictureBox. That isn't how it is meant to be. The PictureBox will still do it's own rendering.
If you really want to do painting of the PictureBox, implement the Paint event of the PictureBox or create a custom control where you draw a rectangle, and a picture.
After you draw the form refresh the form using this :-
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = pictureBox1.CreateGraphics();
Pen bPen=new Pen(Color.Blue,3);
dc.DrawRectangle(bPen,0,0,50,50);
this.Refresh() ;
}

C# PictureBox and Timer don't work together

so I am trying to make a simple game in C# using PictureBox for painting and timer for update functions, but what I noticed is that when I start painting on my picturebox my timer stops working.. I have no idea why..
Here is the picturebox code:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Console.WriteLine("PicBox running!");
if (this.MyGame.InGame)
{
this.pictureBox1.Refresh();
e.Graphics.Clear(Color.White);
MyGame.CurrentMap.Draw(e.Graphics);
//e.Graphics.Dispose(); <- if I uncomment this, then the whole programm just freezes
}
}
Here is the timer code:
private void timer1_Tick(object sender, EventArgs e)
{
Console.WriteLine("Timer running!");
if (this.MyGame.InGame)
{
MyGame.CurrentMap.Update();
MyGame.UpdateTime();
}
}
Here is a method called by MyGame.CurrentMap.Draw(e.Graphics); :
public void Draw(Graphics g)
{
foreach(Planet item in Entities){
item.Draw(g);
}
}
Any help would be greately appreciated. I come from javascript, so I don't really know if I am doing something terribly wrong here.
When a timer tick occurs, you want to repaint your PictureBox. To do this, you should make it so that the PictureBox receives a Paint event. This is what Refresh() does, so the call to this.pictureBox1.Refresh(); goes in the end of timer1_Tick.
It doesn't make sense for the Paint event to contain a call to Refresh, because this, in turn, generates a Paint event.

Drawing rectangle does not work in Windows Forms

The program should draw a rectangle on click. But it does not. Maybe some problem with my understanding of delegates. What's the catch?
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace forms1
{
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//this.Paint+= new PaintEventHandler(MujPaintHandler);
this.Click += new EventHandler(MujClickHandler);
}
public void MujPaintHandler(object sender,PaintEventArgs e)
{
Graphics gfx=e.Graphics;
gfx.FillRectangle(new SolidBrush(Color.DarkViolet),100,100,200,200);
}
public void MujClickHandler(object sender,EventArgs e)
{
this.Text="aaaaa";
this.Paint+= new PaintEventHandler(MujPaintHandler);
}
}
}
The code you've written works for me, but your form's window has to be big enough to show the rectangle.
Diagnostically, the first thing I'd check is whether the title of the form changes to "aaaaa". If it does, then you know the click handler is being called - but maybe you've got a problem with the paint handler. If it doesn't, then for some reason your click handler isn't being called.
Note that this isn't the normal way you'd draw a rectangle on a click in Windows Forms, but I'm assuming this is just a learning exercise.
Try forcing a redraw after assigning the event handler:
public void MujClickHandler(object sender,EventArgs e)
{
this.Text="aaaaa";
this.Paint+= new PaintEventHandler(MujPaintHandler);
this.Invalidate();
}
Also, if you click twice, the event handler gets assigned twice, which is not something you want.
Maybe you have to force a redraw. Does the rect appear if you move the window? Just call the PaintHandler after click.
I think you are only attaching the Paint event handler. You are not invoking the Paint event.
Try this
public void MujClickHandler(object sender,EventArgs e)
{
this.Text="aaaaa";
this.Paint+= new PaintEventHandler(MujPaintHandler);
this.Invalidate();
}
It will only draw the rectangle if it happens to be inside the area that is invalidated to update the text that you change.
When you change the text, it creates a message that the text has to be redrawn, which will call the Paint event to do the drawing. The event will have a Graphics object that is clipped to the rectangle that needs to be redrawn to update the text, so only the part of the rectangle that intersects with the text will be drawn.
You have to cause a redraw that covers the entire rectangle, so the easiest is to cause the whole window to be redrawn:
this.Invalidate();
Note that you should not hook up the Paint event from the Click event handler. That means that the event will be hooked up one more time each click, so after five clicks the Paint event handler will be called five times every time something needs to be redrawn.
Looking at your code, I understand that you are trying to add an eventhandler for paint event on Click... You would also need to invoke the paint event.. Here is a sample code where I am assigning the Paint EventHandler on a button click and raising the paint event on the click as you are doing
public Form1()
{
InitializeComponent();
this.Click += new EventHandler(MujClickHandler);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.ControlKey)
{
MessageBox.Show(e.KeyCode.ToString());
}
}
private void Form1_Load(object sender, EventArgs e)
{
//this.Paint += new PaintEventHandler(MujPaintHandler);
}
public void MujPaintHandler(object sender,PaintEventArgs e)
{
Graphics gfx=e.Graphics;
gfx.FillRectangle(new SolidBrush(Color.DarkViolet),100,100,200,200);
}
public void MujClickHandler(object sender,EventArgs e)
{
this.Text="aaaaa";
this.RaisePaintEvent(this, new PaintEventArgs(this.CreateGraphics(), this.RectangleToClient(new Rectangle())));
}
private void button1_Click(object sender, EventArgs e)
{
this.Paint += new PaintEventHandler(MujPaintHandler);
}

Categories