문제

Wind 오버레이는 onpaint 이벤트에서 그리는 Windows 형태입니다.

로딩 오버레이는 여러 가지 다른 형태로드에서 잘 작동하지만 30 초의 업로드 프로세스 중에 인내심을 보장하기 위해 소환 될 때 제대로 작동하지 않습니다 (Word 문서를 PDF에 인쇄 한 다음 PDF를 SQL Server에 업로드). 이 업로드는 양식에서 일부 데이터를 수집하여 객체에 넣은 다음 전적으로 백그라운드 스레드에서 작동합니다. 로딩 오버레이가 나타나고 첫 번째 프레임 로딩 gif를 표시 한 다음 얼어 붙습니다. onpaint가 발사되고 이미지 프레임이 업데이트되고 있지만 보이지 않습니다.

생성자는 양식을 사용자 정화로 설정합니다.

Sub New()
    InitializeComponent()
    SetStyle(ControlStyles.UserPaint Or ControlStyles.Opaque, True) 
End Sub

그런 다음, 양식에서 하운 이벤트에서 imageAnimator.animate 메소드를 다음과 같습니다.

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

onframechanged 이벤트 핸들러는 양식을 무효화합니다.

Private Sub OnFrameChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    'Force a call to onPaint
    Me.Invalidate()
End Sub

그런 다음 onpaint가 재정의되고 도면을 수행합니다.

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

마지막으로, imageAnimator.Stopanimate 메소드는 양식 폐쇄 이벤트에서 호출됩니다.

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

로딩 오버레이가 호출되고 닫히는 방법은 다음과 같습니다.

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
도움이 되었습니까?

해결책

"일부 com"은 관련이 있습니다. COM의 아파트 스레딩 rulez를 누를 것입니다. Word와 같은 com 객체는 STA 스레드에서 만들어야합니다. 메인 UI 스레드는 자격이 있으며 main ()에서 시작되며 [stathread] 속성이 있습니다. 다른 스레드에서 작성하는 모든 메소드 호출은 COM에 의해 STA 스레드에 자동으로 마샬링됩니다. 당신의 애니메이션을 고무 시키십시오.

이것은 해결하기 쉽지 않습니다. STA 스레드이어야하는 백그라운드 스레드가 필요합니다. STREOD.SETAPARTMENTSTATE ()를 사용하십시오. 메시지 루프를 펌핑하고 application.run ()을 사용하십시오. 코드를 시작하고 루프를 빠져 나가는 것은 어색합니다. setvisiblecore ()를 무시하는 양식을 사용하여 보이지 않도록 피할 수 있습니다.

다른 팁

처음에는 모든 것이 단일 배경 스레드에서 발생합니다. 총 3 가지 방법이 있습니다. 업로드 스레드를 다른 배경 스레드로 옮겼을 때, 모든 것이 "OK"입니다 (완벽하지 않지만 GIF는 여전히 처음에는 조금 점프합니다).

두 번째 배경 스레드로 이동 한 업로드 메소드는 GUI 스레드와 전혀 상호 작용하지 않으며 일부 com (Word) 및 SQL 작업 만 수행합니다. 간단히 말해서, 그것은 효과가 있지만, 나는 여전히 이유를 모른다. 모든 통찰력은 대단히 감사하겠습니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top