LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

.net picturebox examples

Solved!
Go to solution

Does anyone have some basic .net picturebox examples of drawing lines, circles, rectangles, etc?

It looks like a nice replacement for the native picture control but I am having trouble getting anything to work.

I cannot get past an error when creating a pen!

Message 1 of 10
(6,474 Views)
Solution
Accepted by topic author viScience

Here is a basic example, probably not what you were envisioning but this is how business is done at the low level.

 

You have to use the Graphics commands to draw your picture whenever it needs to be redrawn.  This can be window resizing, restore, etc.  It is not a one and done thing, otherwise you have a beautiful picture one minute and blank the next.

 

Step 1.  Register a callback VI for the paint event.  The simplest way is to use the callback VI to do the drawing for you.  I am in the habit of making my callback VI simply a repackaging of the .net event data into a LV user event.  So that is all the callback VI does.

 

Step 2.  In the Event structure redraw the picture (in this case a circle) for each paint event.

 

I am too lazy to handle the startup case right now, but you have to do the initial drawing using the CreateGraphics method of the PicutreBox to draw the first picture.  In the meantime, just drag a corner to resize the window to trigger the first paint event.

 

What I have (mostly) done is create replacements for the native picture functions that generate the equivalent SVG.  I can build a file and use the ActiveX webbrowser to display it.  Not bad, IE lags behind firefox in SVG support, but for static drawing it looks fine.

Download All
Message 2 of 10
(6,463 Views)

Darin - you have made my day!  I just modified your example to draw a perfect antialiased circle and it is a beautiful sight indeed.

I can't wait to try out transparency.  BTW, your SVG ideas sound very cool and is what I originally hoped to be able use.  Do you have

any examples you could share?

Message 3 of 10
(6,451 Views)

Darin,

 

I have taken your idea (with the re-paint user event) and have built a fairly elaborate radar type display.  In my event structure I put in a timeout (100ms) which contains my redraw code, this same redaraw code is also in the paint event case.  This works until another window or popup covers the picturebox and then the whole thing craps out and I have a big red X in the picturebox.  Upon examination I found that once the first timeout occurs, the paint event kicks in and continuously retriggers.  I would have thought that the paint event would only occur when the window resized or was overlayed.  Is there something wrong with my approach? 

0 Kudos
Message 4 of 10
(6,387 Views)

I tried to reproduce this but could not.  I added a timeout and redrew the ellipse during it.  Nothing I did would crash it.  I assume you are using the CreateGraphics method of the picture box to get the graphics item to draw on.

0 Kudos
Message 5 of 10
(6,376 Views)

@sachsm wrote:

This works until another window or popup covers the picturebox and then the whole thing craps out and I have a big red X in the picturebox.  I would have thought that the paint event would only occur when the window resized or was overlayed.  Is there something wrong with my approach? 



If another window pop i'd say it's overlayed. 🙂

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 6 of 10
(6,337 Views)

Hi Darin,

 

I think the problem I am having has to do with the way I am drawing to a .net bitmap instead of directly to the picturebox graphics canvas.

In my test code I send the final bitmap refnum to the PictureBox Image every 100ms, this works fine but have noticed that the act of updating

the PictureBox Image in and of iteself is creating a new paint event.  I would like to migrate my code to work like your example but all of my 

drawing is within a graphics from a .net bitmap and the paint event seems to only contain the graphics from the picturebox canvas.  Any ideas?

 

Picturebox.PNG

0 Kudos
Message 7 of 10
(6,317 Views)

Hi sachsm,

 

Did you have any luck yet with migrating your code to work like the above example?  If you are still having a little trouble, post up your VI and I might have a couple of suggestions.  It sounds like the .NET Dispose() call is clearing out the memory allocation after you have sent the refnum to the PictureBox.  I am not familiar enough with .NET (I'll do some reading) but wouldn't this cause you to open a new instance the next time you want to update the PictureBox image?

| Zach J. | Systems Engineer, HIL and Test Cells | National Instruments |
0 Kudos
Message 8 of 10
(6,300 Views)

@sachsm wrote:

Hi Darin,

 

I think the problem I am having has to do with the way I am drawing to a .net bitmap instead of directly to the picturebox graphics canvas.

In my test code I send the final bitmap refnum to the PictureBox Image every 100ms, this works fine but have noticed that the act of updating

the PictureBox Image in and of iteself is creating a new paint event.  I would like to migrate my code to work like your example but all of my 

drawing is within a graphics from a .net bitmap and the paint event seems to only contain the graphics from the picturebox canvas.  Any ideas?

 

Picturebox.PNG


The Image is the raison d'etre for the PictureBox, and updating its value is certainly a valid reason to fire a Paint Event.  The purpose of the event is to give you a chance to do some additional drawing or whatever.  I usually use it for text or shape overlays on an image.  The Image will always be updated.  This can be a cause of problems when dealing with these types of events, it is possible that an event will re-fire itself if you are not careful.  If you update the image in every paint event, then every paint event will fire another paint event, and so on.

 

If you are generating a bitmap image then it seems to me you could simply pass it on to the PictureBox when it needs to be updated.  No need to deal with Paint events.  This is a hand-rolled version of double buffering where you draw an image behind the scenes and then pass the finished image on to the display. 

 

I guess I am missing something in your implementation. 

0 Kudos
Message 9 of 10
(6,286 Views)

This example is great for introducing the user to the Paint event callback method. However, I was bothered by the Wait function and the flimsiness of this method. If the drawing complexity caused a delay, it could easily break this example.

 

I suspected after reading the documentation that the resources allocated for the callback function are destroyed when the callback leaves memory. So how do you keep the callback VI in memory long enough to allow the application's event case to draw the picture, but not so long as to allow the callbacks to pile up in memory?

 

My solution was to add an Occurrence to the User event data to allow the application's event handler to actually communicate with the callback VI. The occurrence is a "Release" signal to let the callback VI leave memory only (and exactly) after its resources (namely the e.PaintEventArgs.Graphics object) are no longer in use.

 

I've attached the improved example code (LV2018). I left the old callback and event data cluster in there to allow testing of the old way as well. I really like the PictureBox, and hope to use it more.

 

I have also improved the no-callback example posted by @viScience with this post.

_______________________________________________________________
"Computers are useless. They can only give you answers." - Pablo Picasso
0 Kudos
Message 10 of 10
(3,861 Views)