2011-10-17 21 views
2

我正在写一个WinForms窗口在C#中显示约12 ListBox和6 ComboBox控制每个有几百到几千项。显示请等待动画,而用户界面填充

需要一段时间来填充这些。时间不长 - 只需几秒钟,但用户有兴趣看一下,这样他们就知道程序在等待的时候在后台工作。

我有一个通用的“Please Wait”动画无边界顶部窗口,当这种情况发生时出现,但是我在动画方面遇到了问题。

对于那些需要一点时间的大部分任务,我解决这个问题的方式如下:

Program.ShowPleaseWait(); // Show top-most animation 

Thread t = new Thread(stuffToDo); // Run stuffToDo() in separate thread 
t.Start(); 

While (t.IsAlive) 
    Application.DoEvents(); // Run message queue, necessary for animation 

Program.HidePleaseWait(); // Hide top-most animation 

,它工作得很好。有时线程中的东西需要调用某些东西,有时会导致动画中出现小的呃逆,但这通常不是什么大问题。

但是,通过这种形式,线程中的整个代码都是UI代码:填充ListBoxes和ComboBoxes。这意味着所有的东西都必须包含在Invoke块中,这没有任何意义,因为没有必要让它首先在单独的线程中运行。

除了为这个特殊情况报废整个工作线程,并在每个循环中每隔几百次插入一个Application.DoEvents(),我有什么办法可以在控件填充时允许工作动画继续?

回答

3

只需在第二个线程中运行您的动画。您可以拥有多个UI线程,但不允许从除初始化线程之外的线程访问任何UI对象。新线程应接受LoadingAnimationForm(或任何您称之为动画对话框)的实例并致电Application.Run(animForm);当主线程完成填充所有内容时,请致电animForm.Invoke(animForm.Close)。请勿在主线程中调用animForm上的任何其他方法。

+0

工程很棒。感谢那! – Ozzah

+0

事实上,我已经完成并替换了我的代码的所有实例以使用您的方法。 – Ozzah

+0

@Ozzah:很高兴你发现它很有用。 –

1

一种可能的方法是使用空闲时间处理来执行填充代码。所以你创建一个对话框类来显示你的动画。在显示等待对话框的同时,您挂入空闲时间处理事件。空闲时间处理完成后,您会向对话框发送一条消息,告诉其退出。

唯一的问题是你需要组织你的空闲时间事件,所以它每次调用时只执行一点工作,而不是一次性执行所有工作。如果您一次执行完所有操作,则对话框将无法处理并显示更新的等待动画。

+0

一个有趣的建议!这与我正在做的相反 - 使用空闲时间来更新动画。相反,实施起来有点棘手,因为在其他地方使用相同的动画形式。我可以在'ShowPleaseWait'中接受一个泛型函数指针,但将函数分段在空闲时间运行可能会很棘手。 – Ozzah

0

this post摘自:

我要补充这个CodeProject上link

所有你需要的是建立,从工具栏拖动和使用。 LoadingCircle组件没有任何问题。像魅力一样工作,你甚至可以定制它!