3

我正在制作我的第一个 C# GUI。它使用 aBackgroundWorker来运行计算量大的模拟。定期地,模拟报告(通过ProgressChanged事件)需要在 GUI 中显示的大量信息。

GUI 分为多个控件,我希望每个控件都知道如何“更新自身”。

在我的研究中,我发现了很多方法可以做到这一点。

  • 我能想到的是让方法绑定ProgressChanged在 GUI 的每个部分上调用更新方法。
  • 我可以InvalidateGUI 并将每个控件更新方法绑定到Validating事件。
  • 我可以将每个控件的更新方法绑定到ProgressChanged事件。
  • 我可以让每个控件实现INotifyPropertyChanged接口(但我怀疑这是否可行)

在所有这些选项中,哪一个是在事件发生时更新整个 GUI 的最佳实践ProgressChanged?(或者我在左场?)

来自评论:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
  Simulation simulation = new Simulation();
  while(true)
  {
    simulation.RunIteration();
    backgroundWorker.ReportProgress(-1, simulation);
  }
}
4

2 回答 2

3

你不应该做任何特别的事情。

您的 ProgressChanged 处理程序可以“解包”数据并设置控件的相关属性。失效和重绘是自动的,它在 GUI 线程上运行。

您只应该小心更新“过于频繁”。多久太频繁取决于数据量,处理程序应该在下一次更新之前完成。如果没有,请建立一些节流机制。

于 2012-05-16T16:20:11.500 回答
1

ProgressBar 是我推荐的方法。如果您要发送到 GUI 的数据是文本,那么您可以有一个富文本框或只是一个常规文本框,并在进度条更改时将文本传递给它:

public void SomeThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    /* Update progress bar */
    ProgressBar.Value = (e.ProgressPercentage);
    if (e.UserState != null)
    {
        TextBox.Text += (string)e.UserState;
    }
}

对于其他形式的数据,您可以包含一个 If 语句,它在进度条被赋予特定值时执行 X。

但是,如果不了解您具体要做什么,恐怕我无法提供更多帮助。

于 2012-05-16T16:26:52.327 回答