Come si mostrano le GIF animate su un Windows Form (c #)


142

Ho un modulo che mostra i messaggi di avanzamento durante l'esecuzione di un processo abbastanza lungo. È una chiamata a un servizio Web, quindi non posso davvero mostrare una percentuale di percentuale completa su una barra di avanzamento in modo significativo. (Non mi piace particolarmente la proprietà Marquee della barra di avanzamento)

Vorrei mostrare una GIF animata per dare al processo la sensazione di alcune attività (ad esempio file che volano da un computer all'altro come il processo di copia di Windows).

Come fai a fare questo?


per un'immagine animata è possibile utilizzare questo controller. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Risposte:


249

Non è troppo difficile.

  1. Rilascia un riquadro immagine nel modulo.
  2. Aggiungi il file .gif come immagine nella casella immagine
  3. Mostra il riquadro delle immagini durante il caricamento.

Cose da prendere in considerazione:

  • La disabilitazione del riquadro immagine impedirà all'animazione di GIF.

Gif animate:

Se stai cercando gif animate puoi generarle:

AjaxLoad - Ajax Caricamento generatore di gif

Un altro modo di farlo:

Un altro modo che ho scoperto che funziona abbastanza bene è il controllo della finestra di dialogo asincrono che ho trovato nel progetto di codice


5
Imbarazzantemente facile! Il mio "googling" iniziale non lo ha mostrato - forse è troppo ovvio. Grazie.
Stuart Helwig,

1
Tuttavia, la finestra immagine non verrà aggiornata (ridisegnata) durante l'esecuzione del processo.
LarryBud,

Durr, l'ho impostato come immagine di sfondo per errore. L'immagine di sfondo, ragionevolmente, non supporta l'animazione; immagine in primo piano lo fa.
neminem,

@neminem: stesso qui! Questo è il motivo per cui sono qui. Per un po 'ho pensato che pictureBox non supportava le gif di fox (la prima volta che la sto usando)
Jack

@LarryBud Per fare in modo che si aggiorni (ridisegna) durante l'esecuzione del processo, è possibile chiamare Application.DoEvents();. Approccio possibile: la tua logica aziendale genera un evento quando qualcosa è parzialmente fatto, quindi qualsiasi proprietà (ad esempio barra di avanzamento o percentuale) può essere aggiornata e l'animazione può essere aggiornata con Application.DoEvents ()
Do-do-new

12

Ho avuto lo stesso problema. Intero modulo (incluso GIF) che si interrompe per ridisegnare se stesso a causa della lunga operazione in background. Ecco come ho risolto questo.

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

Ho semplicemente creato un altro thread per essere responsabile di questa operazione. Grazie a questo modulo iniziale continua a ridisegnare senza problemi (incluso il mio funzionamento di GIF). ShowProgressGifDelegate e HideProgressGifDelegate sono delegati in forma che impostano la proprietà visibile di pictureBox con gif su true / false.


6

Nota che in Windows, tradizionalmente non usi gif animate, ma piccole animazioni AVI: c'è un controllo nativo di Windows solo per visualizzarle. Esistono anche strumenti per convertire le gif animate in AVI (e viceversa).


Sì, forse è quello che avrei dovuto chiedere. Grazie.
Stuart Helwig,

6
Link allo strumento, s'il vous plaît? O qualsiasi altro riferimento a documentazione, motivi per cui ecc. Sarebbe fantastico. Grazie!
Jeff B

1
Non mi interessa scrivere software Windows tradizionale. Se è supportato dal System.Windows.Forms.PictureBoxcontrollo, userò solo GIF animate.
Mike de Klerk,

3

Se lo metti in un controllo PictureBox, dovrebbe funzionare


2
A meno che non disattivi il modulo;)
Jeff B

1

Non quando si avvia una lunga operazione alle spalle, perché tutto si ferma da quando si è nello stesso thread.


E la modalità thread MTA sembra essere la soluzione peggiore per quanto sto leggendo su StackOverflow.
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

Ho avuto lo stesso problema e mi sono imbattuto in diverse soluzioni implementando che ho dovuto affrontare diversi problemi. Infine, di seguito è quello che ho messo insieme alcuni pezzi di diversi post che hanno funzionato per me come previsto.

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

Ecco il metodo Execution che porta anche a invocare il controllo 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; });
}

Tieni presente che PictureBox è invisibile dalla finestra delle proprietà o esegui di seguito:

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.