ListView不会更新

时间:2015-04-20 09:18:06

标签: c# winforms

我们使用名为MV的MainWindow创建了一个应用程序。

当main启动时,它启动我们的StartProgram方法作为BackgroundWorker和Application.Run(MW);

MainWindow MW = new MainWindow();
BackgroundWorker.DoWork += (obj, e) => StartProgram(MW);
BackgroundWorker.RunWorkerAsync();
Application.Run(MW);

在StartProgram中,我们创建了Patient的实例,我们希望在listView1中显示它们。 我们通过调用此方法来实现这一点,该方法位于MW:

public void SetListSource(Patient p)
{
    ListViewItem item = new ListViewItem("woohoo");
    item.SubItems.Add("a");
    listView1.Items.Add(item);
}

StartProgram在到达listView1.Items.Add(item)时停止;

我们的猜测是,它等待MW(MainWindow),但我们无法弄清楚如何解决它。 我们在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);
}

有人知道如何使SetListSource(...)作为Sort_Button_Click(...)工作吗?

修改 解决了Invoke

2 个答案:

答案 0 :(得分:1)

无法直接从其他线程修改您的GUI 。您需要使用委托并调用您的控件。在你的主题中你必须做:

CONTROL.Invoke(new Action(() =>
{
  CONTROL.Items.Add(item);
}
));

来源:

BackgroundWorker multithread access to form

答案 1 :(得分:0)

可以使用Invoke,但这可能是不必要的。您可以改为使用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();

或者,您可以使用await完成整个事情:

MW.Load += async (s, e)
  {
    var result = await Task.Run(() => SomeCPUWork());
    listView1.Items.Add(((SomeDTO)e.Result).Patient);
  }

关键是,你真的想要在UI和背景中需要做的事情之间进行分离。我绝对不会将表单(或任何其他控件)传递给任何应该在不同线程上执行的方法。