Hi,
New to VB2005 and have run up against a wall, am wondering if I'm just missing a concept somewhere, would greatly appreciate any help/illumination.
THE TASK -- Graphing two functions, end result is two very curvy curves that intersect in many places. Ultimately want to manipulate the resulting picture (erase certain "intersection areas", etc.).
WHAT'S WORKING -- Currently using e.Graphics.DrawLine statements in the _paint section of a Panel. Works great, you get to "see it as you draw it" (very important), the new points & line segments appear on the screen as they're generated.
wHAT'S GIVING HEADACHES -- Discovered I'll need to use getpixel/setpixel to analyse & manipulate the resulting graph (unless there's a better way ), and that a Panel can't use getpixel/setpixel but a PictureBox can. But when I plug the same code into the _paint section of a picturebox, you lose the "see it as you draw it" quality, the picturebox is blank until it's finished graphing then the final result appears suddenly at the end.
THE BIG QUESTION -- Is there a Refresh/DoEvents/something way to get the picturebox to have the "see it as you draw it" quality as when drawing on a panel Or do I need to draw it "live" on the panel first, then do something like grab it with a screenshot (Me.DrawToBitmap ) in order to manipulate it
There's probaby a simple/elegant solution to this, but as a VB2005 newbie I can't seem to find it, am just grinding gears at the moment. Any ideas/tips would be a tremendous help. Thanks.

Painting/Drawing on Panel vs. PictureBox ("See it as you draw it")
hobbledskydiver
First class reply.
Wibs
Himantura
Gang Xiao
I am creating a usercontrol that displays a spectrum. I have been drawing on a PictureBox control. I've got it working pretty well and it all looks good, I can update the spectrum multiple times a second and the picturebox hardly flashes at all. Then I decided to add some keystrokes to the usercontrol and I find out that in VB 2005 they have changed it so the picturebox control doesn't have the Key events. They recommend using a Panel control instead...ok so no problem I change my usercontrol to draw on a panel control instead. Well I've found that the Panel control is very slow at displaying graphics and it flashes like crazy every time it is updated.
So I found this post that you draw to a bitmap first then display the bitmap, so I try it out. I had reverted back to the picturebox control so I modified it to draw to a bitmap and again it worked great, it actually improved upon how I was doing. So I again convert my usercontrol to use the Panel control and find that it still flashes even when drawing to the bitmap.
Are there any controls that I can draw on that display graphics as fast as the Picturebox control and except keystrokes Or is there a way to get the Picturebox control to except keystrokes ...Or is there a way to have the usercontrol keystroke events fire even if one of the internal controls have focus (I have 3 different picturebox controls on my usercontrol)
-Rocks
vladMD
Neat sample!!!
james
aka:Trucker
miimura
Wow, excellent code sample (and really saved my bacon).
Bigtime thanks, jo0ls.
CA_VB2005er
abmeynaks
The Surface class is the clever part.
It has a property to get the graphics for the underlying bitmap.
Use that to draw, and then call refresh or invalidate to update the image.
Then it has fast methods to get and set pixels. I'd recommend grabbing the whole array of pixels and modifying that rather than using the getpixel/setpixel methods as it will be faster.
See the msdn library for bitmapdata, and bitmap.lockbits for more info (and http://www.bobpowell.net/lockingbits.htm ).
' 2005Imports System.DrawingImports System.Drawing.ImagingImports System.Runtime.InteropServices' This call is required by the Windows Form Designer.' Add any initialization after the InitializeComponent() call.Me.Controls.Add(canvas)t = New Timert2 = New Timerinterval = (2 * Math.PI) / 20 ' 20th of the way round a circle' calculate a point on a circle centred on the middle of the graph' rec needs to be a bit bigger for the invalidate call:rec = New Rectangle(rec.X - 1, rec.Y - 1, rec.Width + 2, rec.Height + 2)' join pointsNextNext' lock the bitmap in the canvas, so the pixel array is refreshed' change all lastColor pixels to a new color' things can slow here, so another thread is a good idea, then you can refresh when done.Next' send the array back' update the imageInherits UserControl' custom control to display a bitmap and offer fast getpixel/setpixelMe.SuspendLayout()Me.Width = widthMe.Height = heightMe.ResumeLayout()' use to draw on the bitmapGetReturn g' this is often is msdn examples, but I'm not sure why!:' Draw the bitmap if it exists.g.DrawImageUnscaled(bm, New Point(0, 0))' Lock the image, and transfer the pixels to the pixels array' we don't want to d othis with each getpixel call!' The bitmapdata object has properties to tell you about the bitmap locked in memory.' dimension the array to hold the pixels' copy the memory into the array' scan0 is the location of the top left pixel.' unlock the bitmap' GetPixel from x,y as an int32 - bytes are ARGB - alpha, red, green, blue' dealing with ints is faster than dealing with system.drawing.color' position in the 1d array is:' number of pixels in the rows above (x,y) which is height * number of pixels in a row' PLUS number of pixels in the row leading up to (x,y)Return myPixels((y * bm.Width) + x)Else' Update the bitmap after altering the pixels array with setpixel, setpixelwithcolor or the pixels property' get the bitmapdata' copy the array' unlock the bitmap' refresh (similar to invalidate)Me.Refresh()' getpixel as colorReturn Color.FromArgb(myPixels((y * bm.Width) + x))Else' just get the array...GetReturn myPixels' write modified array back. Call UpdateImage to copy the array to the bitmap' setpixel as integer' setpixel as color' remember to call this to free up resourcesMyBase.Dispose(disposing)Trf_papa
So, have a bitmap available throughout the class. Draw to it whereever you like. Then in the paint event, draw the bitmap to the surface (graphics.drawimageunscaled)
To reduce the drawing time, use control.Invalidate(rectangle). This causes paint to fire, but it only draws the area specified by rectangle. If you don't do this then it will be very slow.
The best option is to create a custom control to host the graph. I've got an example, just need to find it. It also provides a fast get/setpixel method - using bitmapdata objects and lockbits.