Comment afficher des GIF animés sur un formulaire Windows (c #)


142

J'ai un formulaire affichant les messages de progression pendant l'exécution d'un processus assez long. C'est un appel à un service Web, donc je ne peux pas vraiment afficher un pourcentage complet sur une barre de progression de manière significative. (Je n'aime pas particulièrement la propriété Marquee de la barre de progression)

Je voudrais montrer un GIF animé pour donner au processus la sensation d'une activité (par exemple, des fichiers volent d'un ordinateur à un autre comme le processus de copie Windows).

Comment est-ce que tu fais ça?


pour animer une image, vous pouvez utiliser ce contrôleur. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Réponses:


249

Ce n'est pas trop dur.

  1. Déposez une boîte à images sur votre formulaire.
  2. Ajoutez le fichier .gif comme image dans la Picturebox
  3. Montrez la boîte à images lors du chargement.

Choses à prendre en considération:

  • La désactivation de la Picturebox empêchera l'animation du gif.

Gifs animés:

Si vous recherchez des gifs animés, vous pouvez les générer:

AjaxLoad - Générateur de gif de chargement Ajax

Une autre façon de faire:

Une autre façon dont j'ai trouvé qui fonctionne assez bien est le contrôle de dialogue asynchrone que j'ai trouvé sur le projet de code


5
Embarrassant facile! MON "Googling" initial n'a pas montré cela - c'est peut-être trop évident. Merci.
Stuart Helwig

1
Cependant, le Picturebox ne sera pas actualisé (redessiné) pendant l'exécution du processus.
LarryBud

Durr, je l'avais défini comme image de fond par erreur. L'image d'arrière-plan, raisonnablement, ne prend pas en charge l'animation; l'image de premier plan le fait.
neminem

@neminem: Pareil ici! C'est la raison pour laquelle je suis là. Pendant un moment, j'ai pensé que pictureBox ne supportait pas les gifs de renard (la première fois que je l'utilise)
Jack

@LarryBud Pour le faire actualiser (redessiner) pendant l'exécution du processus, vous pouvez appeler Application.DoEvents();. Approche possible: votre logique métier déclenche un événement lorsque quelque chose est partiellement fait, puis toutes les propriétés (par exemple la barre de progression ou le pourcentage) peuvent être mises à jour et l'animation peut être mise à jour avec Application.DoEvents ()
Do-do-new

12

J'ai eu le même problème. Forme entière (y compris gif) arrêtant de se redessiner en raison d'une longue opération en arrière-plan. Voici comment j'ai résolu ce problème.

  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(); 
  }

J'ai simplement créé un autre thread pour être responsable de cette opération. Merci à ce formulaire initial continue de redessiner sans problèmes (y compris mon gif fonctionnant). ShowProgressGifDelegate et HideProgressGifDelegate sont des délégués sous forme qui définissent la propriété visible de pictureBox avec gif sur true / false.


6

Notez que dans Windows, vous n'utilisez traditionnellement pas de Gifs animés, mais de petites animations AVI: il y a un contrôle natif de Windows juste pour les afficher. Il existe même des outils pour convertir des Gifs animés en AVI (et vice-versa).


Oui - c'est peut-être ce que j'aurais dû demander. Merci.
Stuart Helwig

6
Lien vers l'outil, s'il vous plaît? Ou toute autre référence à la documentation, les raisons pour lesquelles, etc., serait formidable. Merci!
Jeff B

1
Je me fiche de l’écriture de logiciels Windows traditionnels. S'il est pris en charge par le System.Windows.Forms.PictureBoxcontrôle, j'utiliserai simplement des GIF animés.
Mike de Klerk

3

Si vous le mettez dans un contrôle PictureBox, cela devrait simplement fonctionner


2
Sauf si vous désactivez le formulaire;)
Jeff B

1

Ce n'est pas le cas lorsque vous démarrez une longue opération en arrière, car tout s'arrête puisque vous êtes dans le même thread.


Et le mode thread MTA semble être la pire solution pour autant que je lis sur StackOverflow.
Yogurtu du

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

J'ai eu le même problème et suis tombé sur différentes solutions en mettant en œuvre que j'avais l'habitude de faire face à plusieurs problèmes différents. Enfin, voici ce que j'ai rassemblé des morceaux de différents articles qui ont fonctionné pour moi comme prévu.

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

Voici la méthode d'exécution qui porte également l'appel du contrôle PictureBox:

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

    // Your main code comes here . . .

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

Gardez à l'esprit que le PictureBox est invisible depuis la fenêtre Propriétés ou faites ci-dessous:

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.