Reputation: 929
I have a command line tool written in c# (that i have the source of) that I am making a gui for in visual studio 2010. In the gui I want to update the progress bar to reflect the progress of the tools operations. How would I signal from inside the tool that progress has been made and to update the progress bar? Some simplified example code of what im doing.
private void doThings_Click(object sender, EventArgs e)
{
myToolInstance.doWorkThatNeedsToReportProgress();
}
The work that is being done by the tool is a series of function calls, normally around 30. I want to update the progress bar each time one of those finishes.
Upvotes: 7
Views: 24220
Reputation: 112362
Create a public property or a public method in the form containing the progress bar
public void SetProgress(int progress)
{
progressBar.Progress = progress;
}
Now you can update the progress bar with
myForm.SetProgress(50);
Another approach is to have a ProgressChanged
event somewhere and let the form subscribe to this event.
public class Tool {
public event Action<int> ProgressChanged;
private void OnProgressChanged(int progress)
{
ProgressChanged?.Invoke(progress);
}
public void DoSomething()
{
...
OnProgressChanged(30);
...
}
}
In the form you would have something like this
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;
}
Upvotes: 17
Reputation: 1312
Golden shovel candidate, nevertheless I came across similar issue and I'd like to share my solution here.
In general, I have a method that will be run asynchronously due to computational complexity. One of the input parameters is the progress bar itself.
Since the ProgressBar
is of nullable type, it is not mandatory when invoking the method.
Inside the method I do the progress bar advancing in its dispatcher - in many cases the method will be run on other thread that owns the progress bar. To handle the null possibility of the progress bar, I use the nullable
operator:
private string MyMethod(int input, ProgressBar progressBar)
{
while(!done)
{
// Do the hard work.
progressBar?.Dispatcher.Invoke(() => progressBar.Value++);
}
}
Now, I need to set the progress bar Maxiumim
before I call the method and it must be set to the expected length.
Some may say that I'm causing great inefficiency calling the dispatcher each time I need to advance the progress bar. Yes, I agree to that, however it all depends on how many steps we need to go through. That's why I've run some quick benchmark.
For my case I had more than 300,000 (three hundred thousands) steps (each step was formatting some data to a string and writing that string to a file). Running the method without the progress bar update was my reference.
With my progress bar being 240 pixels wide I've settled for progress bar maximum of about 300 and updating it accordingly receiving very smooth animation without noticeable performance penalty.
Upvotes: 0