I am creating a small applicaiton for simulating dice roll. To simulate bounces I change the position of the picture randomly. Now to simulate more than one bounce, I used a for loop to continuously change the position of the picture box. But it is not happening as I planned, the form only displays the position of the last loop. I even tried using System.Threading.Thread.Sleep(1000) hoping to show the bounces, but even they show the last loop only.
For bounceCount As Integer = 1 To bounces
bounce(pb_dice1)
bounce(pb_dice2)
System.Threading.Thread.Sleep(3000) 'I need to pause here and show the recent change in position then continue after 3 seconds
Next
the bounce method changes the position of the PictureBox.
How can I pause my for loop, display the newly positioned dices, and then continue after 3 seconds?
Controls don't refresh their graphics until event handlers finish executing. Otherwise, if several changes were made to one or more controls, they would refresh repeatedly when all you really want is the end result.
To force a control to refresh it's graphics, you need to insert the following line before sleeping:
PictureBox1.Refresh()
You may have to change PictureBox1 to the name of another control, of course. Also, it may be worth refreshing the parent control (ie. the control that contains the dice.)
I guess you should use Application.DoEvents() before calling Sleep().
Related
Subject says it all. I'm actually using the label as a pseudo progress bar, so it has a solid blue background color, no text, and I'm increasing its width on each timer tick. This works great except for one oddball case:
If I leave the window up all day, it's fine.
If I minimize for less than a minute and restore, it's fine.
It's only when I minimize for over a minute (long enough that a tick actually fires), then restore the window, the label doesn't repaint. That is, other labels, which aren't dynamically updated during the tick show up when I restore the window, but the special label that IS dynamically updated is not repainted (the pixels I would expect to be blue are the window's background color, a very light gray). Yes, if the restored window sits there until the next tick, the label repaints blue in the expected way. The window isn't locked up - it responds to input. I'm using a Windows.Forms.Timer dragged onto the form, not a System.Timers.Timer in code.
So, user error or OS/.NET framework bug?
Edit 1: Per answer 1 below, the problem is triggered by attempting to read the width of another label. Why would the window's minimized state affect reading the width of a label?
I've isolated it down to this one line of code, which is in the sub that my tick event calls:
fakebar.Width = Int((spanSoFar / spanOverall) * (fakeborder.Width - 2))
Inexplicably, omitting the read of the fakeborder object (a label that does NOT get dynamically updated) fixes the problem:
fakebar.Width = Int((spanSoFar / spanOverall) * (366))
This doesn't seem like user error, but there could be something going on I'm not aware of.
In wxWidgets, is it possible to have on a wxPanel, an object that contains a mouse click event which moves the objects to another location when activated? The movement should be seen as an animation, e.g. Sliding from its initial location to the next location (Using wxTimer?). Is this by any means, possible?
Basically you need to change the position of whatever you are displaying smoothly so a timer at 25 Hz and then update the position a proportion of the movement each time, e.g. if you need to move from 0,0 to 100,200 smoothly in 4 seconds then updating your position by +1,+2 each timer event should do nicely. You may find that you need to invalidate a display area that includes the position before the move and after it to force a redraw but give it a try without first.
This may seem like a very odd thing to do in VBA but I'm curious so hear me out.
I created a procedure that moves an image across the screen when it's clicked. This works, albeit alright, but still - it works.
Here is the code:
'Start primitive animation
Private Sub imgBean_Click()
'Limit for movement to right
Dim coordinates, limit As Integer
coordinates = 0
limit = Form.Width
Do While coordinates < limit
coordinates = coordinates + 5
'Move the image
Me.imgBean.Move coordinates
'Needed to add this to see the image move - updates the form
Form.Repaint
Loop
Debug.Print "Coordinates " & coordinates
Debug.Print limit
'Reset the limit
limit = 0
End Sub
As said before the code works - but while the image is moving the screen is frozen i.e. I can't close the form or interact with other components. (This is similar to blocking the UI thread in the Android environment - something that you never do!)
So is there a way to avoid this?
Thanks
P.S. Setting the focus to the form makes the image sporadically appear and disappear.
Turns out I couldn't find a way to visually prevent interaction with the GUI once the animation has started. I said visually because it is possible to click buttons and enter input while the animation is running.
It involved the use of the DoEvents command which acts as a way of multitasking in MS Access. In mine I added the command above the Do-While loop (see below):
'Essentially allow multitasking
DoEvents
Do While coordinates < limit
coordinates = coordinates + 5
'Move the image
Me.imgBean.Move coordinates
Form.Repaint
Loop
It should be noted that it didn't work when I placed it in the Do-While loop. So, when I started the animation by clicking on the image I could still press the other buttons because I entered a value one one field and clicked a button to convert it to another - while the animation is running.
The only question is how to do this in a visual sense.
I two pictureboxes in my application: One that is mostly just a background image, and another which you can move around changing some settings.
However, depending on my settings (X,Y,Width,Height), a fragment or all of the second picturebox might be "out" of the first picturebox. I don't want that.
Basically, if there is anything in the second picturebox's that is not over the first picturebox, I don't want to show that fragment. I want to cut it.
If I move the second picturebox back inside the first picturebox, then I can see all of it again.
Think of the first picturebox as a "view range"
Fixed:
I set the second picturebox's parent to the first picturebox. Now the second picturebox is cut if it leaves the first picturebox's area.
Sorry for wasting your time :(
Take a look if these threads can help : 1 2
In VisualBasic.Net When I activate a picture box and then draw something on it, it draws and then immediately goes blank. Works fine when I re-draw it, but almost always messes up the first time I draw on it. This has happenned with several different programs, and the help file is no help.
Try setting the DoubleBuffered property
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx
If that's not it, please provide more info.
Usually, if you're drawing something on a picture box or on another control, you have to take over the OnPaint event, and you're responsible of persisting what you draw on this event.
Thank you Andrew, but no help. I'm using .Net Framework 1.1, which does not offer the DoubleBuffered property... it was new in 2.0.
Not sure what additional info to provide.. the code is 300 lines long. When a button is clicked, the code expands my form, makes two picture boxes visible (one on top of the other (the back one is for some graph labels), and then uses some graphic brushes and pens to draw a graph on the front box. There's some database activity and calculations going on in the background at the same time.
I assume you're using the standard PictureBox component. Do you draw in the Paint-Handler? If not then the PictureBox will just erase your painted stuff next time it's asked to redraw itself (erase background etc.).
Yes, I believe I am using the standard picture box.
By Paint-Handler, I assume you mean a [Control].PaintEvent Handler. No I'm not using an event handler to do the drawing... drawing my chart is not an event in itself, but part of a much larger response to a button click event.
If you are saying that having the drawing code be part of a separate and specific handler can solve my problem, than I guess I could raise an internal event every time I want to redraw the chart. But I Would rather just figure out what is causing the PB to redraw itself without being told to.
If you cannot use the DoubleBuffered than you can HIDE a second picture box. You do the drawing in it and once it's completed you draw back to the VISIBLE one. This way the process of drawing is done on the hidden one and the white/flickering will not be shown.