使用C#在表单中添加动态GIF

5

在我的项目中,每当执行长时间的进程时,都会显示一个带有小动画gif文件的小表单。我使用this.Show()打开表单,使用this.Close()关闭表单。以下是我使用的代码。

public partial class PlzWaitMessage : Form
{
   public PlzWaitMessage()
   {
      InitializeComponent();
   }

   public void ShowSpalshSceen()
   {
      this.Show();
      Application.DoEvents();
   }

   public void CloseSpalshScreen()
   {
      this.Close();
   }
}

当表单打开时,图像文件不会立即开始动画。而且,当它开始动画时,该过程通常已经完成或非常接近完成,这使得动画无用。我是否可以在加载表单时立即使gif动画起来?

3个回答

4

为什么不使用线程?学习新东西总是个好主意。

你可以将“长时间处理”的过程放在后台线程中,并使用事件向表示层报告,例如:

// in your "long process" class
public event Action<double> ReportCompletition;

// this method will start long process in separate background thread
public void Start()
{ 
    Thread thread = new Thread(this.LongProcess);
    thread.IsBackground = true;
    thread.Start();
}

private void LongProcess()
{
    // do something
    // report 10% completition by raising event
    this.ReportCompletition(0.1);
    // do something more
    this.ReportCompletition(0.5);
    // ... and so on
}

这样,你只需要在你的表单/UI中实现一个简单的方法,就可以消费这些信息。

public partial class MainApplicationWindow : Form
{
    private LongProcessClass _longProcess;

    public MainApplicationWindow
    {
        this.InitializeComponent();
        this._longProcess = new LongProcessClass();
        // bind UI updating method to long process class event
        this._longProcess.ReportCompletition += this.DisplayCompletitionInfo;
    }

    private void DisplayCompletitionInfo(double completition)
    {  
        // check if control you want to display info in needs to be invoked
        // - request is coming from different thread
        if (control.InvokeRequired)
        {
            Action<double> updateMethod = this.DisplayCompletitionInfo;
            control.Invoke(updateMethod, new object[] { completition });
        }
        // here you put code to do actual UI updating, 
        // eg. displaying status message
        else
        {
            int progress = (int) completition * 10;
            control.Text = "Please wait. Long process progress: " 
                + progress.ToString() + "%";
        }
    }

当然,您可以在长进程内报告任何想要的内容。无论是完成率、准备显示的字符串消息还是其他内容。您还可以使用事件报告长进程已完成、中断或任何您希望报告的长进程数据。
有关此主题的更详细信息,您可能需要查看MSDN教程:线程事件

3
你应该在一个单独的线程中执行“长时间过程”。我建议使用BackgroundWorker。尽管如此,这将使你的代码更加复杂。其中一个主要原因是,你不能从后台线程与UI通信。
还要注意链接页面中的警告:

注意

当使用任何形式的多线程时,你可能会遇到非常严重和复杂的错误。在实现使用多线程的任何解决方案之前,请参阅Managed Threading Best Practices。

如果这太难了,你可以从“长时间过程”代码中频繁地调用Application.DoEvents。
无论你选择哪种方式,都会使用户能够与你的表单进行交互。例如关闭它。你应该意识到这一点。

当然是指应用程序的过程,而不是所显示的GIF过程。 - Ignacio Soler Garcia
由于我缺乏经验,我不想使用线程。我正在使用Application.DoEvents()函数。在我的代码中,我使用以下代码调用ShowSpalshSceen()。PlzWaitMessage pMess = new PlzWaitMessage(); pMess.ShowSpalshSceen(); LoadReport(); pMess.CloseSpalshScreen();这里我做错了吗? - Rabin
顺便提一下,我的窗体上的图片框位于一个面板之上,该面板填充了整个小消息窗体。 - Rabin
@Rabin,如果您希望在执行长时间进程时更新UI,则必须使用线程。它们并不难,特别是如果您使用BackgroundWorker类来控制它。 - ChrisF
像ChrisF所说,使用线程会更好。不使用线程将使您缺乏经验。 - GvS
我想你是对的。谢谢大家帮助我。 - Rabin

0

在PictureBox中使用gif,并使用Form pWait = new Form(); pWait.Show();打开它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接