是否可以在后台线程中填充ObjectListView?

问题描述 投票:2回答:1

我有一个应用程序,其中我将几千个项目添加到列表视图。此操作可能需要一些时间,但对应用程序来说很好。但是,我仍然希望在填充列表时运行选取框进度栏,以便用户可以看到正在发生的事情。 进度栏锁定,因为UI线程正忙于添加项目。

试图从后台工作人员中填充列表视图控件,但是进度栏仍被锁定。它使我了解到,由于列表控件位于UI线程中,因此从后台工作人员填充它实际上并没有任何更改。

在这种情况下,有没有办法让进度条仍在运行?

我想知道进度条是否可能在另一个线程中运行,但是我不知道该怎么做,或者是否有可能。

这是我的代码来说明(添加2200个对象):

List.SuspendLayout();

StatusText.Text = "Populating the list...";
ProgressBar.Style = ProgressBarStyle.Marquee;

List.SetObjects(items);

List.ResumeLayout();

我也尝试过使用BeginUpdate()EndUpdate()方法,但是没有明显的效果(我假设它也暂停并恢复了布局)。

c# multithreading winforms backgroundworker objectlistview
1个回答
0
投票

由于您在注释中给了我指针,我能够确定填充列表时的加载延迟:这不是由于列表控件本身引起的。只要将项目添加到列表中,就可以按预期访问要在列中显示的属性。但是,其中某些属性需要从数据库和磁盘中额外加载数据。

为了解决该问题,我创建了一个单独的后台工作程序,以在将项目添加到列表之前初始化项目的内部数据缓存。之后,实际显示列表最多只需要几秒钟。

以说明:

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.";
}
© www.soinside.com 2019 - 2024. All rights reserved.