2

我正在用 C# 编写一个 WinForms 窗口,它显示大约 12 个ListBox和 6 个ComboBox控件,每个控件有几百到几千个项目。

填充这些需要一点时间。没多久——只有几秒钟,但用户可以看到一些东西是件好事,这样他们就知道程序在等待时正在后台运行。

我有一个通用的“请稍候”动画无边框最顶层窗口,在发生这种情况时会出现,但是我在动画方面遇到了问题。

对于大多数需要一点时间的任务,我通过以下方式解决这个问题:

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()在每个循环中插入大约一百个左右的插入之外,我还能做些什么来让工作动画在控件被填充时继续?

4

3 回答 3

3

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

于 2011-10-17T04:30:48.917 回答
1

一种可能的方法是使用空闲时间处理来执行填充代码。因此,您创建了一个对话框类,用于显示您的等待动画。在显示等待对话框的同时挂钩空闲时间处理事件。一旦空闲时间处理完全完成,您将向对话框发送一条消息,告诉它退出。

唯一的复杂性是您需要组织空闲时间事件,以便每次调用它时只执行一点工作,而不是一次性执行所有工作。如果您一次性执行所有操作,则对话框永远没有机会处理并显示更新的等待动画。

于 2011-10-17T04:26:10.370 回答
0

取自这篇文章

我可以添加这个 CodeProject链接吗?

您所需要的只是构建、从工具栏拖动并使用。该LoadingCircle组件完全没有任何问题。像魅力一样工作,您甚至可以自定义它!

于 2013-03-13T18:03:46.747 回答