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!
I'm curious what the LV Picture Control lacks that you get from the .NET version. (This isn't a challenge to your assertion that it's needed; rather, I'd just like to learn more about when to explore the use of .NET controls in place of their LV counterparts. I've already found a handful of strong cases for ditching the native LV controls, but I haven't done enough fancy work with Picture Controls to run into any major limitations.)
Some of my favorite features of the .NET picturebox (over the LV Picture Control) are:
Unfortunately I don't have a example to share right now...
This all sounds very interesting, but I've not used the .NET PictureBox before so I've been investigating. I can create a System.Drawing.Pen and a place a PictureBox class into a front panel container, but the System.Drawing.Graphics classes needed to draw lines and rectangles etc. have no public constructors and I can't see a way to call them. I'm no .NET expert, so there may be a way to call them in LabVIEW yet (are they event driven?) but I'm struggling to see it from my brief experiment.
Here is an example to get started. Generally picturebox's get refreshed in the repaint event but I am trying to emulate the native picture control so I am updating in my own loop. I am not sure why I need to .05s delay before the btmap dispose, maybe I need to make the picturebox a synchronous control.
Looks like you moved on from your Pen object error and are getting somewhere quite nicely with the PictureBox tools now
When I tried to call the Graphics.FromImage method I got a broken run arrow, but I hadn't thought to cast the Bitmap object to an Image type first so maybe that's where I was going wrong.
In reference to the delay - I'm no expert either, but I believe the .NET bitmap contains the GDI object, i.e. contains information for a defined part of the screen display, and that bitmap is referenced in the image object, so by disposing of the bitmap, you lose the reference to what is supposed to be in that place on the screen. If a re-paint event triggers in the meantime, that part of the screen doesn't know what to do! To test this theory, I replaced the wait in your "simple drawing.vi" with a feedback node - that way you create the next bitmap and apply that to the image before you dispose of the previous bitmap, so there is always valid information available. Also for clear comparison with your vi (in terms of CPU usage, memory etc), I modfied the timeout value to 66ms which is actually roughly what the original code was running at (time for the .NET code and the 50ms timer). IMHO, the event structure timeout case is not a great way to do animation, better a timed loop, or in this case on the "value change" event, but certainly fine for this example! Works a treat, and you can reduce the timeout without errors occuring.
I took the example and the update suggested by @DCatz and played with making it event-based. This works until you resize the window. An unhandled exception pops up, which doesn't make for a very good user experience.
It turns out that the Timeout event and the constant redrawing of the Image is entirely unnecessary. You don't have to worry about when to Dispose of the Bitmap if you never dispose of it at all (until you quit). All you have to do is Clear the Bitmap to reset your drawing buffer before new Draw calls.
I changed the example to an event-based version that updates the Bitmap buffer when a control value is changed. I limited the event case to only 1 event in the event queue (per control) to keep the events from piling up as you slide the sliders (a common issue with sliders and window resizing).
The best part of this is that you can resize the window, minimize it, cover it up, whatever, and it never faults or has any redraw issues (with no code!). This actually surprised me that it worked so well without implementing the Paint callback as in this post.
A good explanation of the double-buffering process used in this example can be found in this short video on YouTube (link).
I have attached the updated example in 2018 (and back-saved it to 2012). I hope this helps others who are exploring the PictureBox control. I think it's a very powerful alternative to the scripted Picture control, and LabVIEW should provide a proper API for it.