Làm cách nào để hiển thị GIF động trên Biểu mẫu Windows (c #)


142

Tôi có một biểu mẫu hiển thị các thông báo tiến trình khi một quá trình khá dài chạy. Đó là một cuộc gọi đến một dịch vụ web vì vậy tôi thực sự không thể hiển thị con số phần trăm hoàn chỉnh trên thanh tiến trình một cách có ý nghĩa. (Tôi không đặc biệt thích thuộc tính Marquee của thanh tiến trình)

Tôi muốn hiển thị một GIF hoạt hình để cung cấp cho quá trình một số hoạt động (ví dụ: các tệp bay từ máy tính này sang máy tính khác như quá trình sao chép Windows).

Làm thế nào để bạn làm điều này?


để tạo hình ảnh động, bạn có thể sử dụng bộ điều khiển này. codeproject.com/Tips/1004624/Gif-viewer-Snipper-control
xwpedram

Câu trả lời:


249

Nó không quá khó.

  1. Thả một hình ảnh vào mẫu của bạn.
  2. Thêm tệp .gif làm hình ảnh trong hình ảnh
  3. Hiển thị tượng hình khi bạn đang tải.

Những điều cần xem xét:

  • Vô hiệu hóa hình ảnh sẽ ngăn gif hoạt hình.

Ảnh hoạt hình:

Nếu bạn đang tìm kiếm gifs hoạt hình, bạn có thể tạo chúng:

AjaxLoad - Trình tạo gif Ajax Đang tải

Một cách khác để làm điều đó:

Một cách khác mà tôi đã thấy hoạt động khá tốt là điều khiển hộp thoại async mà tôi tìm thấy trong dự án mã


5
Xấu hổ dễ! "Googling" ban đầu của tôi đã không cho thấy điều này - có lẽ nó quá rõ ràng. Cảm ơn.
Stuart Helwig

1
Tuy nhiên, tượng hình sẽ không làm mới (vẽ lại) như quá trình thực thi.
LarryBud

Durr, tôi đã đặt nó làm hình nền do nhầm lẫn. Hình nền, hợp lý, không hỗ trợ hình ảnh động; hình ảnh nền trước nào.
neminem

@neminem: Tương tự ở đây! Đó là lý do tại sao tôi ở đây. Trong một thời gian, tôi nghĩ rằng PictureBox không hỗ trợ gif cáo (lần đầu tiên tôi sử dụng nó)
Jack

@LarryBud Để làm cho nó làm mới (vẽ lại) khi quá trình đang thực thi, bạn có thể gọi Application.DoEvents();. Cách tiếp cận có thể: logic nghiệp vụ của bạn kích hoạt một sự kiện khi một cái gì đó được thực hiện một phần, sau đó bất kỳ thuộc tính nào (ví dụ như thanh tiến trình hoặc tỷ lệ phần trăm) có thể được cập nhật và hình ảnh động có thể được cập nhật với Application.DoEvents ()
Do-do-new

12

Tôi đã từng gặp vấn đề tương tự. Toàn bộ hình thức (bao gồm cả gif) dừng để vẽ lại chính nó do hoạt động lâu làm việc trong nền. Đây là cách tôi giải quyết điều này.

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

Tôi chỉ đơn giản tạo ra một chủ đề khác để chịu trách nhiệm cho hoạt động này. Nhờ hình thức ban đầu này tiếp tục vẽ lại mà không gặp vấn đề gì (bao gồm cả gif của tôi hoạt động). ShowProTHERGifDelegate và HideProTHERGifDelegate là các đại biểu ở dạng đặt thuộc tính hiển thị của imageBox với gif thành true / false.


6

Lưu ý rằng trong Windows, theo truyền thống, bạn không sử dụng Gifs hoạt hình, nhưng hoạt hình AVI nhỏ: có một điều khiển riêng của Windows chỉ để hiển thị chúng. Thậm chí còn có các công cụ để chuyển đổi Gifs hoạt hình sang AVI (và ngược lại).


Vâng - có lẽ đó là những gì tôi nên hỏi. Cảm ơn.
Stuart Helwig

6
Liên kết đến công cụ, vì vậy có phải không? Hoặc bất kỳ tài liệu tham khảo nào khác, lý do tại sao, vv, sẽ là tuyệt vời. Cảm ơn!
Jeff B

1
Tôi không quan tâm đến việc viết phần mềm Windows truyền thống. Nếu nó được hỗ trợ bởi System.Windows.Forms.PictureBoxđiều khiển, tôi sẽ chỉ sử dụng GIF động.
Mike de Klerk

3

Nếu bạn đặt nó trong điều khiển PictureBox, nó sẽ hoạt động


2
Trừ khi bạn vô hiệu hóa biểu mẫu;)
Jeff B

1

Nó không phải là khi bạn bắt đầu một hoạt động dài phía sau, bởi vì tất cả mọi thứ STOPS kể từ khi bạn cùng một chủ đề.


Và chế độ luồng MTA dường như là giải pháp tồi tệ nhất theo như tôi đang đọc trên 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

Tôi có cùng một vấn đề và đã tìm ra các giải pháp khác nhau bằng cách thực hiện mà tôi đã từng đối mặt với một số vấn đề khác nhau. Cuối cùng, bên dưới là những gì tôi đặt một số phần từ các bài đăng khác nhau làm việc cho tôi như mong đợi.

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

Đây là phương thức Thực thi cũng thực hiện việc gọi điều khiển 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; });
}

Hãy ghi nhớ, PictureBox là vô hình từ Cửa sổ Thuộc tính hoặc thực hiện bên dưới:

private void ComparerForm_Load(object sender, EventArgs e)
{
    pictureBox1.Visible = false;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.