从线程而不是 C# 中的原始线程更新 ListView

Update ListView from a thread not the original thread in C#

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

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

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

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

我的列表视图可能需要一个解决方案,但如果您有答案,请清楚地解释为什么以及它是如何工作的,因为我需要彻底了解它。你也可以在尝试这种做法时注意到我的风险。

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

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

内部发生的事情是用于绘制 Windows 的图形资源(它也可以应用于 Android)它需要使用钢笔、画笔和那些类型的对象.

这些对象属于最初实例化它们的线程的上下文。这通常发生在主线程中,但如果您要在不同于主线程的单独线程中创建图形对象(在本例中为 List),则该特定线程将是您控件的 "owner" 线程。

如果你想在需要刷新 UI 的控件中更改某些内容(需要使用钢笔、画笔等),你必须从与 "owns" 相同的线程执行此操作你的控制。这就是您需要使用 Invoke 的原因。

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

如果清楚了请告诉我。

编辑。无论如何,您的代码看起来有点奇怪,因为您正在从自己的列表中迭代填充列表。这样做不是更有意义吗?:

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

在不知道上下文的其余部分的情况下,这对我来说听起来更合乎逻辑。