I'm trying to use a loading overlay on top of a Windows form that adds a 50% opaque layer on top of a windows form with a loading GIF, while it does what it needs to do in a background thread. The overlay is a windows form that I'm drawing in the onPaint event.
The loading overlay works fine on multiple different form loads, but fails to work properly when summoned to ensure patience during a 30 second upload process (That Prints a Word Document to PDF, then uploads that PDF to a SQL Server). This upload collects some data from the form, puts it into an Object, then operates entirely on a background thread. The loading overlay will appear, show the first frame loading GIF, then just freeze. The onPaint is getting fired and the image frame is being updated, but it isn't visible
Constructor sets the form to be UserPainted:
Sub New()
InitializeComponent()
SetStyle(ControlStyles.UserPaint Or ControlStyles.Opaque, True)
End Sub
Then, in the Form.Shown event the ImageAnimator.Animate method is called:
Private Sub LoadingOverlay_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
If Not currentlyAnimating Then
ImageAnimator.Animate(animatedImage, AddressOf Me.OnFrameChanged)
currentlyAnimating = True
End If
End Sub
The onFrameChanged Event Handler just Invalidates the form:
Private Sub OnFrameChanged(ByVal sender As Object, ByVal e As System.EventArgs)
'Force a call to onPaint
Me.Invalidate()
End Sub
Then onPaint is overridden and does the drawing:
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
'Get the next frame ready for rendering
ImageAnimator.UpdateFrames()
'Draw the next frame in the animation.
e.Graphics.DrawImage(Me.animatedImage, GetCenter(Me.animatedImage.Size))
TextRenderer.DrawText(e.Graphics, strStatus, Me.Font, GetTextLocation(Me.animatedImage.Size), Color.White, Color.Black)
End Sub
Finally, the ImageAnimator.StopAnimate method is called in the Form Closing event:
Private Sub LoadingOverlay_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
If currentlyAnimating Then
ImageAnimator.StopAnimate(animatedImage, AddressOf Me.OnFrameChanged)
currentlyAnimating = False
End If
End Sub
Here's how the loading overlay is being called and closed:
Private Sub ShowLoadingOverlay()
If Not blnLoadingOverlayVisible Then
Me.Enabled = False
patience = New LoadingOverlay()
patience.Location = Point.Add(parent.PointToScreen(Me.Location), New Size(0, parent.ToolStrip.Height + parent.MenuStrip.Height))
patience.Size = Me.Size
patience.Show()
patience.BringToFront()
blnLoadingOverlayVisible = True
End If
End Sub
Private Sub HideLoadingOverlay()
If blnLoadingOverlayVisible Then
'Close loading overlay'
patience.Close()
patience.Dispose()
patience = Nothing
Me.Enabled = True
blnLoadingOverlayVisible = False
End If
End Sub