C# - 在向ListView添加项目时更新标签

时间:2012-11-26 15:40:07

标签: c#

我有一个ListView,我填充了很多项目,超过3000.这可能需要15秒。 每次我添加一个项目,我想更新一个标签,说明到目前为止已添加了多少项目。 为此,我使用此代码:

foreach (FileInfo f in dir.GetFiles("*.*", SearchOption.AllDirectories))
{
    DateTime dt = GetDateTakenFromImage(Path.Combine(f.Directory.ToString(), f.Name));
    count++;
    labelLoadedLeft.Text = "Loading " + count + " files so far";
    ListViewItem lSingleItem = lv.Items.Add(f.Name);

    lSingleItem.SubItems.Add(dt.ToString("dd MMMM yyyy"));
    lSingleItem.Tag = Path.Combine(f.Directory.ToString(), f.Name);
}

不幸的是,在加载所有项目之前,标签不会显示。

我理解这与我在thr UI线程上进行冗长操作的事实有关,我应该使用后台工作来完成这项工作。

有没有人知道如何使用后台工作者的好的和简单的例子。到目前为止,我所发现的对我来说太复杂或太复杂。

谢谢

Crouz

4 个答案:

答案 0 :(得分:1)

如果您只想更新标签,则应更新它。

labelLoadedLeft.Text = "Loading " + count + " files so far";
labelLoadedLeft.Update();

您使用的是哪个版本的VS / C#?使用VS2012 / C#5.0,您可以利用新的“等待”功能。它使代码易于阅读和更新UI可以在不调用等的情况下完成

答案 1 :(得分:1)

你可以使用BackgroundWorker来做,这是一个例子,http://dotnetforum.net/topic/34729-how-to-cancel-backgroundworker-during-getfiles/

但是,在获得所有文件的列表之前,UI永远不会显示任何内容。正如你所说,这很慢。

使用EnumerateFiles方法,http://msdn.microsoft.com/en-us/library/dd383458(v=vs.100).aspx,一次返回一个文件。

答案 2 :(得分:1)

后台工作人员最容易通过TPL处理,假设您正在使用.NET 4.0。您可以使用如下代码在后台启动工作人员:

Task.Factory.StartNew( () =>
{
   // Background Worker Stuff goes here
}, TaskCreationOptions.LongRunning);

然后,您可以将您的工作人员的工作放在另一个班级/职能部门,并从yield return获取DoWork()结果,并为您提供IEnumerable<T>所返回的任何内容。像这样使用foreach循环:

foreach(var item in DoWork())
{
   // Update UI
}

意味着您可以在结果返回时更新UI。 Yield return将允许您在整个可枚举返回之前处理项目。但要小心 - yield return隐式在程序中设置一个状态机,所以除非你需要这样的功能,否则使用这个习惯用法会非常浪费。

答案 3 :(得分:0)

您可能不需要它。在ListView上使用Begin / EndUpdate。

http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.beginupdate.aspx

这将阻止绘制项目,直到它们全部加载为止。你将无法维持一个计数,但我根本没有看到它的好处,特别是如果这使得它太快而无关紧要。