Bir Windows Formunda (c #) animasyonlu GIF'leri nasıl gösterirsiniz?


142

Oldukça uzun bir süreç çalışır gibi ilerleme iletileri gösteren bir form var. Bir web hizmetine yapılan bir çağrıdır, bu yüzden gerçekten ilerleme çubuğunda tam yüzde yüzdesi gösteremiyorum. (Özellikle ilerleme çubuğunun Marquee özelliğini sevmiyorum)

Sürece bazı etkinlik hissi vermek için animasyonlu bir GIF göstermek istiyorum (örneğin bir bilgisayardan diğerine Windows kopyalama işlemi gibi uçan dosyalar).

Bunu nasıl yapıyorsun?


hareketli bir görüntü için bu denetleyiciyi kullanabilirsiniz. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Yanıtlar:


249

Çok zor değil.

  1. Formunuza bir resim kutusu bırakın.
  2. .Gif dosyasını resim kutusuna resim olarak ekleyin
  3. Yükleme sırasında resim kutusunu gösterin.

Dikkate alınması gerekenler:

  • Resim kutusunun devre dışı bırakılması, gif'in canlandırılmasını önleyecektir.

Hareketli Gifler:

Eğer animasyonlu gif arıyorsanız onları üretebilirsiniz:

AjaxLoad - Ajax Yükleme gif jeneratörü

Bunu yapmanın başka bir yolu:

Oldukça iyi çalıştığını bulduğum başka bir yol, kod projesinde bulduğum zaman uyumsuz iletişim denetimi


5
Utanç verici derecede kolay! İlk "Google'ım" bunu göstermedi - belki çok açıktır. Teşekkürler.
Stuart Helwig

1
Ancak resim kutusu, işlem yürütülürken yenilenmez (yeniden çizilir).
LarryBud

Durr, yanlışlıkla arka plan görüntüsü olarak ayarlamıştım. Arka plan görüntüsü makul olarak animasyonu desteklemez; ön plan görüntüsü yapar.
neminem

@neminem: Burada aynı! Bu yüzden buradayım. Bir süre için pictureBox'ın tilki giflerini desteklemediğini düşündüm (ilk kez kullanıyorum)
Jack

@LarryBud İşlem yürütülürken yenilenmesine (yeniden çizilmesine) neden olmak için arayabilirsiniz Application.DoEvents();. Olası yaklaşım: iş mantığınız, bir şey kısmen yapıldığında bir olayı tetikler, ardından hangi özellikler (örneğin ilerleme çubuğu veya yüzde) güncellenebilir ve Animation Application.DoEvents ()
Do-do-new

12

Ben de aynı problemi yaşadım. Tüm form (gif dahil) arka planda çalışan uzun çalışma nedeniyle kendini yeniden çizmeyi durduruyor. İşte bunu nasıl çözdüm.

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

Bu işlemden sorumlu olacak başka bir iş parçacığı oluşturdum. Bu başlangıç ​​formu sayesinde (gif çalışmam dahil) sorunsuz yeniden çizmeye devam ediyor. ShowProgressGifDelegate ve HideProgressGifDelegate, gif özellikli pictureBox öğesinin visible özelliğini true / false olarak ayarlayan delegelerdir.


6

Windows'da geleneksel olarak animasyonlu Gif'ler değil, küçük AVI animasyonları kullandığınızı unutmayın: sadece onları görüntülemek için bir Windows yerel kontrolü vardır. Animasyonlu Gif'leri AVI'ye (ve tersi) dönüştürmek için araçlar bile vardır.


Evet - belki de sordum. Teşekkürler.
Stuart Helwig

6
Araca bağlantı, s'il vous plaît? Ya da belgelere başka herhangi bir atıf, neden, vb. Çok iyi olurdu. Teşekkürler!
Jeff B

1
Geleneksel Windows yazılımı yazmayı umursamıyorum. System.Windows.Forms.PictureBoxKontrol tarafından destekleniyorsa , sadece animasyonlu GIF'leri kullanacağım.
Mike de Klerk

3

Bir PictureBox denetimine koyarsanız, sadece


2
Formu devre dışı bırakmazsanız;)
Jeff B

1

Arkasında uzun bir operasyon başlattığınızda olmaz, çünkü aynı iş parçacığında olduğunuzdan beri her şey DURDUR.


Ve MTA iş parçacığı modu StackOverflow üzerinde okuduğum kadarıyla en kötü çözüm gibi görünüyor.
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

Aynı sorunu yaşadım ve birkaç farklı sorunla karşılaştığım uygulamaları uygulayarak farklı çözümlerle karşılaştım. Son olarak, aşağıda benim için beklendiği gibi çalışan farklı gönderilerden bazı parçaları bir araya getirdim.

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

PictureBox denetimini çağırmayı da yürüten Yürütme yöntemi:

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

    // Your main code comes here . . .

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

PictureBox'ın Özellikler Penceresinden görünmez olduğunu unutmayın veya aşağıdakileri yapın:

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.