¿Cómo mostrar GIF animados en un formulario de Windows (c #)

142

Tengo un formulario que muestra mensajes de progreso a medida que se ejecuta un proceso bastante largo. Es una llamada a un servicio web, por lo que realmente no puedo mostrar un porcentaje completo en una barra de progreso de manera significativa. (No me gusta especialmente la propiedad Marquee de la barra de progreso)

Me gustaría mostrar un GIF animado para darle al proceso la sensación de cierta actividad (por ejemplo, archivos que vuelan de una computadora a otra como el proceso de copia de Windows).

¿Cómo haces esto?

Stuart Helwig
fuente
para una imagen animada puedes usar este controlador. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Respuestas:

249

No es muy dificil.

  1. Coloque un cuadro de imagen en su formulario.
  2. Agregue el archivo .gif como imagen en el cuadro de imagen
  3. Muestre el cuadro de imagen cuando esté cargando.

Cosas a tener en cuenta:

  • Deshabilitar el cuadro de imagen evitará que el gif sea animado.

Gifs animados:

Si buscas gifs animados, puedes generarlos:

AjaxLoad - Ajax Loading gif generator

Otra forma de hacerlo:

Otra forma que he encontrado que funciona bastante bien es el control de diálogo asíncrono que encontré en el proyecto de código

FryHard
fuente
55
¡Vergonzosamente fácil! MI "Google" inicial no mostró esto, tal vez es demasiado obvio. Gracias.
Stuart Helwig, el
1
Sin embargo, el cuadro de imagen no se actualizará (redibujará) mientras se ejecuta el proceso.
LarryBud
Durr, lo había configurado como imagen de fondo por error. La imagen de fondo, razonablemente, no admite animación; imagen en primer plano hace.
neminem
@neminem: ¡Lo mismo aquí! Es por eso que estoy aquí. Por un tiempo pensé que pictureBox no soportaba gifs de zorros (la primera vez que lo uso)
Jack
@LarryBud Para que se actualice (redibuje) mientras se ejecuta el proceso, puede llamar Application.DoEvents();. Enfoque posible: la lógica de su negocio dispara un evento cuando algo se hace parcialmente, luego cualquier propiedad (por ejemplo, barra de progreso o porcentaje) se puede actualizar y la animación se puede actualizar con Application.DoEvents ()
Do-do-new
12

Yo tuve el mismo problema. La forma completa (incluido el gif) se detiene para volver a dibujarse debido a una operación prolongada que funciona en segundo plano. Así es como resolví esto.

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

Simplemente creé otro hilo para ser responsable de esta operación. Gracias a este formulario inicial continúa dibujándose sin problemas (incluido mi trabajo GIF). ShowProgressGifDelegate y HideProgressGifDelegate son delegados en forma que establecen la propiedad visible de pictureBox con gif en true / false.

Aruch
fuente
6

Tenga en cuenta que en Windows, tradicionalmente no utiliza Gif animados, sino pequeñas animaciones AVI: hay un control nativo de Windows solo para mostrarlos. Incluso hay herramientas para convertir GIF animados a AVI (y viceversa).

PhiLho
fuente
Sí, tal vez eso es lo que debería haber preguntado. Gracias.
Stuart Helwig, el
66
Enlace a la herramienta, s'il vous plaît? O cualquier otra referencia a la documentación, razones por las cuales, etc., sería genial. ¡Gracias!
Jeff B
1
No me importa escribir el software tradicional de Windows. Si es compatible con el System.Windows.Forms.PictureBoxcontrol, solo usaré GIF animados.
Mike de Klerk
3

Si lo pones en un control PictureBox, debería funcionar

Grank
fuente
2
A menos que desactive el formulario;)
Jeff B
1

No lo hace cuando comienzas una operación larga, porque todo se detiene ya que estás en el mismo hilo.


fuente
Y el modo de hilo MTA parece ser la peor solución en lo que estoy leyendo en 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
Gehan Fernando
fuente
0

Tuve el mismo problema y encontré diferentes soluciones mediante la implementación que solía enfrentar varios problemas diferentes. Finalmente, a continuación se muestran algunas piezas de diferentes publicaciones que funcionaron para mí como se esperaba.

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

Aquí está el método de ejecución que también lleva a invocar el control 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; });
}

Tenga en cuenta que PictureBox es invisible desde la ventana Propiedades o haga lo siguiente:

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
M. Fawad Surosh
fuente