我有一个应用程序,其中我将几千个项目添加到列表视图。此操作可能需要一些时间,但对应用程序来说很好。但是,我仍然希望在填充列表时运行选取框进度栏,以便用户可以看到正在发生的事情。 进度栏锁定,因为UI线程正忙于添加项目。
我试图从后台工作人员中填充列表视图控件,但是进度栏仍被锁定。它使我了解到,由于列表控件位于UI线程中,因此从后台工作人员填充它实际上并没有任何更改。
在这种情况下,有没有办法让进度条仍在运行?
我想知道进度条是否可能在另一个线程中运行,但是我不知道该怎么做,或者是否有可能。
这是我的代码来说明(添加2200个对象):
List.SuspendLayout();
StatusText.Text = "Populating the list...";
ProgressBar.Style = ProgressBarStyle.Marquee;
List.SetObjects(items);
List.ResumeLayout();
我也尝试过使用BeginUpdate()
和EndUpdate()
方法,但是没有明显的效果(我假设它也暂停并恢复了布局)。
由于您在注释中给了我指针,我能够确定填充列表时的加载延迟:这不是由于列表控件本身引起的。只要将项目添加到列表中,就可以按预期访问要在列中显示的属性。但是,其中某些属性需要从数据库和磁盘中额外加载数据。
为了解决该问题,我创建了一个单独的后台工作程序,以在将项目添加到列表之前初始化项目的内部数据缓存。之后,实际显示列表最多只需要几秒钟。
以说明:
private void PopulateList()
{
StatusText.Text = "Populating the list...";
// start the background worker
PopulateListWorker.RunWorkerAsync();
}
private void Worker_PopulateList_DoWork(object sender, DoWorkEventArgs e)
{
// run the data cache initialization
}
private void Worker_PopulateList_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
private void Worker_PopulateList_Completed(object sender, RunWorkerCompletedEventArgs e)
{
List.SuspendLayout();
List.SetObjects(items);
List.ResumeLayout();
progressBar.Value = 0;
StatusText.Text = "All done.";
}