从一个线程更新ListView而不是C#

时间:2017-02-10 06:35:23

标签: c# multithreading listview controls cross-thread

我已经知道要更新控件,我可以使用Invoke Action

progressBar1.Invoke(new Action(() => { progressBar1.Maximum = 0; }));

但这仅适用于作为单一数据的控制属性。现在我有一个线程需要更改列表视图项的列表视图集合,清除它然后更新新项目,新文本和图标图像。它们之间有什么不同,整数或bool与列表,数组或整数,bool甚至组件,控件的集合相比较。我可以简单地添加

string[] newItemText = {"item1", "item2", ...};
listView1.Invoke(new Action() => {
    i = 0;
    foreach(var item in listView1.Items)
    {
         item.Text = newItemText[i];
         i++; 
    }
}));

我的列表视图可能需要一个解决方案,但如果您有答案,请详细说明原因和方法,因为我需要彻底了解它。你也可以注意到我在尝试这种练习时的风险。

编辑:问题不在于如何从其他线程更新控件。关于何时以及为什么需要这样做而不是那样做的IT。此外,我需要知道更新单个数据和更新整个数据集之间的不同。

1 个答案:

答案 0 :(得分:1)

更新值或向列表添加更多元素没有区别。

内部发生的是用于在Windows中绘制的图形资源(它也可以应用于Android),它需要使用钢笔,画笔和这些类型的对象。

这些对象属于最初实例化它们的线程的上下文。这通常发生在主线程中,但是如果你要创建图形对象,在这种情况下是List,在一个单独的线程中,主要的,那个特定线程将是你控件的“所有者”线程。

如果你想在Control中更改需要刷新UI的东西(需要使用钢笔,画笔等),你必须从“拥有”你的Control的同一个线程中做到这一点。这就是你需要使用Invoke的原因。

这是主要原则。如果将标量值更新为整数,或者向列表中添加元素,则没有区别。两者都需要使用图形资源,因此两者都需要从拥有Control的同一个线程中调用。

如果清楚的话,请告诉我。

编辑。在任何情况下,您的代码看起来都有点奇怪,因为您正在从自己的列表中填充List迭代。这样做会更有意义吗?:

string[] newItemText = {"item1", "item2", ...};
listView1.Invoke(new Action() => {
   for(int i = 0; i < newItemText.length; i++)
   {
     listView1.add(newItemText[i]);
   }
});

在不知道其他情况的情况下,这对我来说听起来更合乎逻辑。