[英]ListView wont update
We've made an Application with a MainWindow called MV. 我们用MainWindow制作了一个名为MV的应用程序。
When main starts it launches our StartProgram method as a BackgroundWorker and the Application.Run(MW); 当main启动时,它将启动我们的StartProgram方法作为BackgroundWorker和Application.Run(MW);。
MainWindow MW = new MainWindow();
BackgroundWorker.DoWork += (obj, e) => StartProgram(MW);
BackgroundWorker.RunWorkerAsync();
Application.Run(MW);
In StartProgram we create instances of Patient, which we want to show in our listView1. 在StartProgram中,我们创建Patient的实例,并将其显示在listView1中。 We do this by calling this method, which is in MW:
我们通过调用此方法来实现此目的,该方法在MW中:
public void SetListSource(Patient p)
{
ListViewItem item = new ListViewItem("woohoo");
item.SubItems.Add("a");
listView1.Items.Add(item);
}
StartProgram stalls when it reaches listView1.Items.Add(item); StartProgram到达listView1.Items.Add(item);时停止。
Our guess is, that it waits for MW (MainWindow), but we can't figure out how to fix it. 我们的猜测是,它等待MW(MainWindow),但我们不知道如何解决它。 We have a button in MW, that does somethis similar, except it only sends "1" and "a" to the listView1.
我们在MW中有一个按钮,它的功能与此类似,只不过它仅将“ 1”和“ a”发送到listView1。
private void Sort_Button_Click(object sender, EventArgs e)
{
ListViewItem item = new ListViewItem("1");
item.SubItems.Add("a");
listView1.Items.Add(item);
}
Does anybody know how to make SetListSource(...) work as Sort_Button_Click(...)? 有人知道如何使SetListSource(...)用作Sort_Button_Click(...)吗?
EDIT Solved with Invoke 编辑通过调用解决
You can't modify your GUI directly from another thread . 您不能直接从另一个线程修改GUI 。 You need to use a delegate and invoke your control.
您需要使用委托并调用您的控件。 In your thread you have to do:
在您的线程中,您必须执行以下操作:
CONTROL.Invoke(new Action(() =>
{
CONTROL.Items.Add(item);
}
));
Source: 资源:
BackgroundWorker multithread access to form BackgroundWorker对表单的多线程访问
You can use Invoke
, but that's probably unnecessary. 您可以使用
Invoke
,但这可能是不必要的。 You can use BackgroundWorker.RunWorkerCompleted
event instead: 您可以改用
BackgroundWorker.RunWorkerCompleted
事件:
BackgroundWorker.DoWork +=
(s, e) =>
{
e.Result = DoAllTheComplicatedWork();
}
BackgroundWorker.RunWorkerCompleted +=
(s, e) =>
{
// Back on the UI thread, we can do whatever we want
listView1.Items.Add(((SomeDTO)e.Result).Patient);
}
BackgroundWorker.RunWorkerAsync();
Or, you can do the whole thing using await
: 或者,您可以使用
await
完成整个操作:
MW.Load += async (s, e)
{
var result = await Task.Run(() => SomeCPUWork());
listView1.Items.Add(((SomeDTO)e.Result).Patient);
}
The key point is, you really want a separation between the UI and whatever you need to do in background. 关键是,您确实希望将UI与后台需要执行的操作分开。 I definitely wouldn't pass a form (or any other control) to any method that's supposed to be executed on a different thread.
我绝对不会将表单(或任何其他控件)传递给应该在不同线程上执行的任何方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.