Bagaimana Anda menampilkan GIF animasi di Formulir Windows (c #)

142

Saya memiliki formulir yang menunjukkan pesan kemajuan saat proses yang cukup panjang berjalan. Ini adalah panggilan ke layanan web sehingga saya tidak dapat benar-benar menunjukkan persentase angka lengkap pada progress bar secara bermakna. (Saya tidak terlalu suka properti Marquee dari progress bar)

Saya ingin menunjukkan GIF animasi untuk memberikan proses rasa aktivitas (misalnya file terbang dari satu komputer ke komputer lain seperti proses penyalinan Windows).

Bagaimana kamu melakukan ini?

Stuart Helwig
sumber
untuk animasi suatu gambar Anda dapat menggunakan pengontrol ini. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Jawaban:

249

Itu tidak terlalu sulit.

  1. Letakkan picturebox ke formulir Anda.
  2. Tambahkan file .gif sebagai gambar di picturebox
  3. Tampilkan kotak gambar saat Anda memuat.

Hal-hal yang perlu dipertimbangkan:

  • Menonaktifkan picturebox akan mencegah gif dari animasi.

Gif animasi:

Jika Anda mencari gif animasi, Anda dapat membuatnya:

AjaxLoad - Ajax Memuat generator gif

Cara lain untuk melakukannya:

Cara lain yang saya temukan yang berfungsi cukup baik adalah kontrol dialog async yang saya temukan pada proyek kode

FryHard
sumber
5
Sangat mudah! Inisial "Googling" saya tidak menunjukkan ini - mungkin terlalu jelas. Terima kasih.
Stuart Helwig
1
Namun picturebox tidak akan me-refresh (redraw) sebagai proses yang dijalankan.
LarryBud
Durr, saya telah menetapkannya sebagai gambar latar belakang karena kesalahan. Gambar latar belakang, secara wajar, tidak mendukung animasi; gambar foreground tidak.
neminem
@neminem: Sama di sini! Itu sebabnya saya di sini. Untuk sementara saya pikir pictureBox tidak mendukung fox gif (pertama kali saya menggunakannya)
Jack
@LarryBud Untuk membuatnya menyegarkan (redraw) saat proses sedang dijalankan, Anda dapat menelepon Application.DoEvents();. Kemungkinan pendekatan: logika bisnis Anda menjalankan suatu peristiwa ketika sesuatu dilakukan sebagian, maka properti apa pun (misalnya bilah kemajuan atau persentase) dapat diperbarui dan animasi dapat diperbarui dengan Application.DoEvents ()
Do-do-new
12

Saya memiliki masalah yang sama. Seluruh bentuk (termasuk gif) berhenti untuk menggambar ulang sendiri karena operasi yang panjang bekerja di latar belakang. Inilah cara saya memecahkan ini.

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

Saya hanya membuat utas lain untuk bertanggung jawab atas operasi ini. Berkat formulir awal ini terus menggambar ulang tanpa masalah (termasuk gif saya berfungsi). ShowProgressGifDelegate dan HideProgressGifDelegate adalah delegasi dalam bentuk yang mengatur properti terlihat dari pictureBox dengan gif ke true / false.

Aruch
sumber
6

Perhatikan bahwa di Windows, Anda biasanya tidak menggunakan animasi Gif, tetapi sedikit animasi AVI: ada kontrol asli Windows hanya untuk menampilkannya. Bahkan ada alat untuk mengubah animasi Gif ke AVI (dan sebaliknya).

PhiLho
sumber
Ya - mungkin itu yang seharusnya saya tanyakan. Terima kasih.
Stuart Helwig
6
Tautan ke alat, apa lagi? Atau referensi lain untuk dokumentasi, alasan mengapa, dll., Akan bagus Terima kasih!
Jeff B
1
Saya tidak peduli menulis perangkat lunak Windows tradisional. Jika didukung oleh System.Windows.Forms.PictureBoxkontrol, saya hanya akan menggunakan animasi GIF.
Mike de Klerk
3

Jika Anda meletakkannya di kontrol PictureBox, itu hanya akan berfungsi

Nenek
sumber
2
Kecuali Anda menonaktifkan formulir;)
Jeff B
1

Tidak ketika Anda memulai operasi yang panjang di belakang, karena semuanya berhenti karena Anda berada di utas yang sama.


sumber
Dan mode thread MTA tampaknya menjadi solusi terburuk sejauh yang saya baca di 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
sumber
0

Saya memiliki masalah yang sama dan menemukan solusi yang berbeda dengan menerapkan yang saya gunakan untuk menghadapi beberapa masalah yang berbeda. Akhirnya, di bawah ini adalah apa yang saya satukan beberapa bagian dari posting yang berbeda yang bekerja untuk saya seperti yang diharapkan.

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

Berikut adalah metode Eksekusi yang juga membawa memohon kontrol 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; });
}

Perlu diingat, PictureBox tidak terlihat dari Properties Window atau lakukan di bawah ini:

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