I create graphics thru Graphics.FillEllipse(...) which is drawn on Picturebox. After all drawing is done I would like to save current state of Picturebox with points drawn. Can someone point me to right direction, or what is the best approach to achieve desired functionality?
Thanks in advance ;)
Windows Forms painting on controls (including of course PictureBox) is immediate mode drawing. Whatever you are drawing must be repainted in some event handler, or it is lost on the next repaint. Typically the Control.Paint event. Perhaps you should move the drawing logic into some method that takes a Graphics instance as a parameter. When you want to draw to a bitmap, for example, you can create a graphics object from the bitmap using Graphics.FromImage(...) and pass it to the painting method. Whatever you "paint" in the bitmap stays in the bitmap: no need to repaint. Then you can save or do whatever you want with the bitmap.
See immediate versus retained mode:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff684178%28v=vs.85%29.aspx
Related
I have a Bitmap loaded in a picturebox. My problem is that I want it to move smoothly when using a mouse. Is there some super-duper function for moving and image by some pixels very fast?
Or do I have to repaint a picturebox completely every time I move by a single pixel (somehow with a LockBits method)?
I need it to run fast with no flickering.
Obviously you have to redraw the whole box every time you move, the trick is that you don't recalculate the whole area you see, you keep the whole (or at least a large chunk) of the picture loaded, and just specify wich part to draw.
An interesting concept is described here, and it might work for your needs - assumes your bitmap is not tiled, i.e. can be loaded all at once:
Put the PictureBox in a Panel, using the panel as your viewport.
I have used grahics in a panel. At start of the program I draw some points in the panel and after that I want to draw lines connecting those points. Problem is when I press tab button the graphics created disappear (but this happens once in the program). Next problem is I want to clear the panel I used following code to clear panel:
Panel1.Invalidate();
But this only clears the lines but not those points that were initially created. Does anyone has a simple solution because I don't want to recreate the panel.
Technical Detail: to draw initial points in panel, paint event of panel1 is used:
Graphics gfx = e.CreateGraphics()
For lines, there is a seprate function that is called on button click and in that I used:
Graphics gfx = Panel1.CreateGraphics();
Another button that is used to clear panel has following code:
Panel1.invalidate();
but it only clears the line graphics, not those initial points.
I was making a mistake by creating initial points in the paint event of panel1. So everytime i call
Panel1.Invalidate();
it recalls that paint event and those points are redrawn and not cleared.
Do you save the points in some sort of collection and draw them in the Paint event?
Then you should empty the collection and then call the Invalidate
The panel is redrawn inside the paint event. It means that you have to draw everything inside this method, instead of accessing the graphics context directly.
This explains why everything you draw when you use Graphics gfx = Panel1.CreateGraphics(); is lost every time the control is redrawn, since during the paint event, you are only drawing the initial points, nothing more.
Imagine there's a picturebox which loads a monochrome image. And there is a need to make few color scribbles on it. I have no background with graphics. Would it be just a pen drawing pixels or something more complex I don't know.
Target language is C#. Technology: WinForms.
I think the easiest way to achieve what you want would be to create a very lightweight retained mode drawing system. Keep track of all the positions where the user has scribbeled and draw dots/circles/lines/rubberducks/whatever at these positions in the PictureBox's Paint event. On mousedown+move events, call the PictureBox' Invalidate() function. The original picture must either be painted underneath or in the class' OnPaintBackground (which IMO is more elegant).
This tutorial should get you started:
https://web.archive.org/web/20121006140255/http://www.bobpowell.net/backtrack.htm
I have a image drawn in an winform app and i designed a brush that moves after the cursor. The Brush is drawn every time so the image keeps flashing because the image is also redrawn . How can i avoid this ?
Regards,
Alex Badescu
Use double-buffering. Draw each frame to some kind of memory bitmap representing the back buffer and once it's drawn show it on the first.
For more info read here:
http://msdn.microsoft.com/en-us/library/b367a457.aspx
Simply set the form's DoubleBuffered property to true. That should solve the flickering.
No reason to make it more advanced than this, in such a simple scenario.
I just started on the .net compact framework. I want to draw a Sudoku field on the screen. So I put down a PictureBox and defined a method for the Paint event:
private void pictureBoxPlayfield_Paint(object sender, PaintEventArgs e)
{
// use e.Graphics to draw the grid, numbers and cursor
}
This works, but you can see as the grid is drawn. So my question is, what is the right/better way to create such a custom control? Is there maybe a way to enable double buffering?
There is no built-in support for double buffering in the Compact Framework. You can add it yourself, PictureBox already supports the Image property. Create a Bitmap in the constructor and assign it to Image. You don't need the Paint event anymore, the one provided by PictureBox already draws it to the screen.
Whenever the image needs to change, create a Graphics object with Graphics.FromImage(), passing the PB's Image and draw your stuff. Call the PB's Invalidate() method to tell it that it needs to redraw the image. If you still see flicker, override the PB's OnPaintBackground() method and do nothing.
The only other consideration is handling resizing, you'd need a larger or smaller Bitmap. Not so sure that would be necessary for a game.