我有一个用c#编写的命令行工具(我有源代码),我在visual studio 2010中制作gui。在gui我想更新进度条以反映工具操作的进度。我如何从工具内部发出已取得进展的信号并更新进度条? 我正在做的一些简化示例代码。
private void doThings_Click(object sender, EventArgs e)
{
myToolInstance.doWorkThatNeedsToReportProgress();
}
该工具正在进行的工作是一系列函数调用,通常在30左右。我想在每次完成其中一个时更新进度条。
答案 0 :(得分:12)
在包含进度条的表单中创建公共属性或公共方法
public void SetProgress(int progress)
{
progressBar.Progress = progress;
}
现在您可以使用
更新进度条myForm.SetProgress(50);
另一种方法是在某处发生ProgressChanged
事件,并让表单订阅此事件。
public class Tool {
public event Action<int> ProgressChanged;
private void OnProgressChanged(int progress)
{
var eh = ProgressChanged;
if (eh != null) {
eh(progress);
}
}
public void DoSomething()
{
...
OnProgressChanged(30);
...
}
}
在表格中你会有这样的东西
private Tool _tool;
public MyForm () // Constructor of your form
{
_tool = new Tool();
_tool.ProgressChanged += Tool_ProgressChanged;
}
private void Tool_ProgressChanged(int progress)
{
progressBar.Progress = progress;
}
答案 1 :(得分:0)
尽管我遇到了类似的问题,但我还是想在这里分享我的解决方案。
通常,由于计算复杂性,我有一种方法将异步运行。输入参数之一是进度条本身。
由于ProgressBar
为可空类型,因此在调用该方法时不是强制性的。
在方法内部,我在其调度程序中执行进度条前进-在许多情况下,该方法将在拥有进度条的其他线程上运行。为了处理进度条的无效可能性,我使用了nullable
运算符:
private string MyMethod(int input, ProgressBar progressBar)
{
while(!done)
{
// Do the hard work.
progressBar?.Dispatcher.Invoke(() => progressBar.Value++);
}
}
现在,我需要在调用该方法之前设置进度条Maxiumim
,并且必须将其设置为预期的长度。
有些人可能会说,每次我需要提高进度栏时,都会给调度员打电话造成效率低下。是的,我同意这一点,但是这完全取决于我们需要执行多少步骤。这就是为什么我要运行一些快速基准测试的原因。
就我而言,我有超过300,000(三十万)个步骤(每个步骤是将一些数据格式化为字符串并将该字符串写入文件)。我的参考是运行没有进度条更新的方法。
在进度条为240像素宽的情况下,我已经确定最大进度条为300左右,并相应地对其进行更新,从而获得了非常流畅的动画,而没有明显的性能损失。