Wie zeigen Sie animierte GIFs in einem Windows Form (c #)


142

Ich habe ein Formular, in dem Fortschrittsmeldungen angezeigt werden, während ein ziemlich langer Prozess ausgeführt wird. Es handelt sich um einen Anruf bei einem Webdienst, sodass ich auf einem Fortschrittsbalken nicht wirklich einen Prozentsatz der vollständigen Zahl anzeigen kann. (Ich mag die Marquee-Eigenschaft des Fortschrittsbalkens nicht besonders.)

Ich möchte ein animiertes GIF zeigen, um dem Prozess das Gefühl einer Aktivität zu geben (z. B. Dateien, die wie ein Windows-Kopiervorgang von einem Computer auf einen anderen fliegen).

Wie machst Du das?


Für animierte Bilder können Sie diesen Controller verwenden. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Antworten:


249

Es ist nicht zu schwer.

  1. Legen Sie eine Bilderbox auf Ihrem Formular ab.
  2. Fügen Sie die GIF-Datei als Bild in die Bildbox ein
  3. Zeigen Sie die Bilderbox beim Laden an.

Dinge zu beachten:

  • Durch Deaktivieren der Picturebox wird verhindert, dass das GIF animiert wird.

Animierte Gifs:

Wenn Sie nach animierten Gifs suchen, können Sie diese generieren:

AjaxLoad - Ajax Gif-Generator wird geladen

Ein anderer Weg, es zu tun:

Eine andere Art und Weise , dass ich gefunden habe , das funktioniert ganz gut die Steuerung asynchroner Dialog ist , dass ich auf dem gefundenen Code Projekt


5
Peinlich einfach! Mein anfängliches "Googeln" hat dies nicht gezeigt - vielleicht ist es zu offensichtlich. Vielen Dank.
Stuart Helwig

1
Die Bildbox wird jedoch während der Ausführung des Prozesses nicht aktualisiert (neu gezeichnet).
LarryBud

Durr, ich hatte es versehentlich als Hintergrundbild festgelegt. Das Hintergrundbild unterstützt vernünftigerweise keine Animation. Vordergrundbild tut.
Neminem

@neminem: Gleich hier! Darum bin ich hier. Für eine Weile dachte ich, dass pictureBox keine Fox-Gifs unterstützt (zum ersten Mal benutze ich es)
Jack

@LarryBud Damit es während der Ausführung des Prozesses aktualisiert (neu gezeichnet) wird, können Sie aufrufen Application.DoEvents();. Möglicher Ansatz: Ihre Geschäftslogik löst ein Ereignis aus, wenn etwas teilweise erledigt ist. Dann können alle Eigenschaften (z. B. Fortschrittsbalken oder Prozentsatz) aktualisiert und die Animation mit Application.DoEvents ()
Do-do-new

12

Ich hatte das gleiche Problem. Die gesamte Form (einschließlich GIF) wird angehalten, um sich selbst neu zu zeichnen, da im Hintergrund lange Vorgänge ausgeführt werden. Hier ist, wie ich das gelöst habe.

  private void MyThreadRoutine()
  {
   this.Invoke(this.ShowProgressGifDelegate);
   //your long running process
   System.Threading.Thread.Sleep(5000);
   this.Invoke(this.HideProgressGifDelegate);
  }

  private void button1_Click(object sender, EventArgs e)
  {
   ThreadStart myThreadStart = new ThreadStart(MyThreadRoutine);
   Thread myThread = new Thread(myThreadStart);
   myThread.Start(); 
  }

Ich habe einfach einen anderen Thread erstellt, der für diesen Vorgang verantwortlich ist. Dank dieser ersten Form wird das Neuzeichnen ohne Probleme fortgesetzt (einschließlich meiner GIF-Funktion). ShowProgressGifDelegate und HideProgressGifDelegate sind Delegaten in Form, die die sichtbare Eigenschaft von pictureBox mit gif auf true / false setzen.


6

Beachten Sie, dass Sie in Windows traditionell keine animierten Gifs verwenden, sondern nur kleine AVI-Animationen: Es gibt ein natives Windows-Steuerelement, um sie nur anzuzeigen. Es gibt sogar Tools zum Konvertieren von animierten Gifs in AVI (und umgekehrt).


Ja - vielleicht hätte ich das fragen sollen. Vielen Dank.
Stuart Helwig

6
Link zum Tool, s'il vous plaît? Oder ein anderer Verweis auf Dokumentation, Gründe usw. wäre großartig. Vielen Dank!
Jeff B

1
Es ist mir egal, ob ich traditionelle Windows-Software schreibe. Wenn es vom System.Windows.Forms.PictureBoxSteuerelement unterstützt wird , verwende ich nur animierte GIFs.
Mike de Klerk

3

Wenn Sie es in ein PictureBox-Steuerelement einfügen, sollte es einfach funktionieren


2
Es sei denn, Sie deaktivieren das Formular;)
Jeff B

1

Dies ist nicht der Fall, wenn Sie eine lange Operation hinter sich lassen, da alles anhält, da Sie sich im selben Thread befinden.


Und der MTA-Thread-Modus scheint die schlechteste Lösung zu sein, soweit ich auf StackOverflow lese.
Yogurtu

1
Public Class Form1

    Private animatedimage As New Bitmap("C:\MyData\Search.gif")
    Private currentlyanimating As Boolean = False

    Private Sub OnFrameChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Me.Invalidate()

    End Sub

    Private Sub AnimateImage()

        If currentlyanimating = True Then
            ImageAnimator.Animate(animatedimage, AddressOf Me.OnFrameChanged)
            currentlyanimating = False
        End If

    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        AnimateImage()
        ImageAnimator.UpdateFrames(animatedimage)
        e.Graphics.DrawImage(animatedimage, New Point((Me.Width / 4) + 40, (Me.Height / 4) + 40))

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        BtnStop.Enabled = False

    End Sub

    Private Sub BtnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStop.Click

        currentlyanimating = False
        ImageAnimator.StopAnimate(animatedimage, AddressOf Me.OnFrameChanged)
        BtnStart.Enabled = True
        BtnStop.Enabled = False

    End Sub

    Private Sub BtnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStart.Click

        currentlyanimating = True
        AnimateImage()
        BtnStart.Enabled = False
        BtnStop.Enabled = True

    End Sub

End Class

0

Ich hatte das gleiche Problem und stieß bei der Implementierung auf verschiedene Lösungen, mit denen ich verschiedene Probleme hatte. Im Folgenden habe ich einige Teile aus verschiedenen Posts zusammengestellt, die wie erwartet für mich funktioniert haben.

private void btnCompare_Click(object sender, EventArgs e)
{
    ThreadStart threadStart = new ThreadStart(Execution);
    Thread thread = new Thread(threadStart);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

Hier ist die Ausführungsmethode, mit der auch das PictureBox-Steuerelement aufgerufen wird:

private void Execution()
{
    btnCompare.Invoke((MethodInvoker)delegate { pictureBox1.Visible = true; });
    Application.DoEvents();

    // Your main code comes here . . .

    btnCompare.Invoke((MethodInvoker)delegate { pictureBox1.Visible = false; });
}

Beachten Sie, dass die PictureBox im Eigenschaftenfenster nicht sichtbar ist oder gehen Sie wie folgt vor:

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.