Archived

This topic is now archived and is closed to further replies.

edotorpedo

C#: Nothing drawn to pictureBox on startup

Recommended Posts

Hi, I''m new to C#, and I have a little problem. In my form_load function, I try to draw a grid in a pictureBox (using Graphics and Pen object). I''m doing everything correct, but nothing is drawn when I load the application (it does execute the drawing code normally). Weird thing is: When I put the same function in a button-click-eventhandler, the grid is drawn as it should. What could I be missing, I tried updating and refreshing the pictureBox on leaving form_load, but it still doens''t draw anything. Thanks, Edo

Share this post


Link to post
Share on other sites
Your code should probably be put in the "Paint" event, instead of Form_Load. Form_Load is called before the form is displayed, so your drawing is not actually done. Windows only draws the stuff that will be visible.

Cédric

Share this post


Link to post
Share on other sites

BTW: I tried putting the code in the Paint-event, but this doesn''t work either. Really strange...

Must I work with the PaintEventArgs parameter which I get on calling the Paint-event? I just use plain picMain.CreateGraphics().

Edo

Share this post


Link to post
Share on other sites
You should add a new override for the OnPaint event of the class that represents the panel you are drawing to. It would go like this:

protected override void OnPaint(PaintEventArgs e)
{
Graphics dc = e.Graphics;
// Use dc to draw whatever you want here

base.OnPaint(e);
}

That's the correct way to do it and it will stay drawn even if other windows pass in front of it, or if you minimize and then restore the form (the way you did it with the mouse button, if you do either what you painted will be lost).

[edited by - blackghost on July 27, 2003 7:51:30 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by edotorpedo
This could work. But why doesn't work when I put the code after the InitializeComponent() function in the form-constructor? Is this because the form isn't drawn at that time?

Yup. When you put your code in the Click event, what would happen if you moved another window above your form, and then moved it away? The window would leave marks (or erase what you have drawn; I'm not sure). The same problem happens if the window is not shown at all when the drawing is done; nothing is drawn.

If you come from a VB background, I can tell you that, AFAIK, C# does not have an AutoRedraw property. Or, at least, it's not turned on by default.

And yes, you should use the arguments provided to the Paint event function.

Cédric

[edited by - Cedric on July 27, 2003 10:21:21 PM]

Share this post


Link to post
Share on other sites

Allright, it now draws the board at startup, but now it draws wrong when I call the function with my button-event.

Drawing function:


public drawBoard(Graphics g) {

float width = (g.ClipBounds.Width + 2) / GRID_SIZE;
// draw board


}

// calling functions

private void btStart_Click(object sender, System.EventArgs e)
{
gameBoard.drawBoard(picMain.CreateGraphics());
}

private void picMain_Paint(object sender, PaintEventArgs e)
{
gameBoard.drawBoard(e.Graphics);

}



Somehow the graphics object created by picMain.createGraphics is different from the one that e.Graphics returns. How can I retrieve the width of my picturebox correctly when I only have a Graphics object?

Thanks

Edo

Share this post


Link to post
Share on other sites
When a Paint event is fired, you are not guaranteed that you will be able to paint on the entire surface. Usually only the portion that has been invalidated will be available for you to paint at. This is a Good Thing(TM). This doesn''t mean that you will have to change your drawing code to compensate for this(but you can, and in some cases it might be an advantage for you to do so) since Windows manages this for you behind the scenes.

quote:

How can I retrieve the width of my picturebox correctly when I only have a Graphics object?


How about myPictureBox.Width?

Furthermore, you shouldn''t be calling the drawBoard method directly like you do(with the CreateGraphics etc). Instead, just call Invalidate on the control:

private void btStart_Click(object sender, System.EventArgs e)
{
gameBoard.Invalidate();
}

This will trigger a paint event, and your paint event handler will be called.



AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.

Share this post


Link to post
Share on other sites
quote:
Original post by edotorpedo

Allright, it now draws the board at startup, but now it draws wrong when I call the function with my button-event.

Drawing to the form, in most common cases, should only be done in Paint, or you''ll have problems, like the one you have shown. Set a flag saying that the picture has been clicked, call invalidate, and draw it in the Paint event.

Cédric

Share this post


Link to post
Share on other sites

Thanks all,

The invalidate() trick did the job. The reason why I couldn''t use pictureBox.width was that I wanted to pass the graphics-object to my painting-class.

I now retrieve my width using g.ClipBounds.Width (adding 2 for the outer lines).

Edo

Share this post


Link to post
Share on other sites