Incrementing Text in Circular Progress Bar - c#

private void _btnOK_Click(object sender, EventArgs e)
{
_label1.Hide();
_label2.Hide();
_label3.Hide();
for(int i = 1; i <= 100; i++)
{
Thread.Sleep(5);
_circularprogressbar.Value = i;
_circularprogressbar.Update();
}
}
private void LoadingScreen_Load(object sender, EventArgs e)
{
_circularprogressbar.Value = 0;
_circularprogressbar.Minimum = 0;
_circularprogressbar.Maximum = 100;
}
}
}
This is my code. What i want to do is, i want to have a text inside the progress bar that shows the percentage of the progress from 1 to 100 percent.
what can i add to my code?
thank you

Here is what i would do:
private void _btnOK_Click(object sender, EventArgs e)
{
_label1.Hide();
_label2.Hide();
_label3.Hide();
for(int i = 1; i <= 100; i++)
{
_circularprogressbar.Value = i;
_percent_lable_name.Text = string.Format("{0}%", _circularprogressbar.Value);
_circularprogressbar.Update();
}
}
private void LoadingScreen_Load(object sender, EventArgs e)
{
_circularprogressbar.Value = 0;
_circularprogressbar.Minimum = 0;
_circularprogressbar.Maximum = 100;
}
}
See if that helps you!
Thanks
Techcraft7 :)

That Thread.Sleep(5) is blocking your entire UI thread. If you want to have your UI responsive, while the progress takes place, you need to make a separate thread for it. Something like this:
private void _btnOK_Click(object sender, EventArgs e)
{
_label1.Hide();
_label2.Hide();
_label3.Hide();
Task.Factory.StartNew(() =>
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(5);
Invoke((Action)(() =>
{
_circularprogressbar.Value = i;
_circularprogressbar.Update();
}));
}
});
}
Note that you will need t use Invoke to BeginInvoke to access UI components from inside that thread.

Related

fix progress bar in WinForms

The problem is the label gets displayed before the progress-bar is completed. How do I make the label display only after the progress-bar is fully complete?
I tried changing the max values to a higher number but it didn't work.
public partial class dload : Form
{
public dload()
{
InitializeComponent();
}
private void dload_Load(object sender, EventArgs e)
{
label1.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (i = 0; i <= 5000; i++)
{
progressBar1.Value = i;
if (i == 5000)
{
label1.Visible = true;
}
}
}
}
Actually, Your code run very vast, it is about less than a second to set value from 0% to 100% ! But
ProgressBar has two styles for displaying the current status (Classic and Continues).
In Continues mode if the progress value went to 100% from 0% the control will show an animation, which is not display the real and accurate progress. You can set a delay via Thread.Sleep() and show your label immediately after the for loop to find out to what i happening !
The Below code will work:
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (i = 0; i <= 5000; i++)
{
Thread.Sleep(1);
progressBar1.Value = i;
}
label1.Visible = true;
}
This is an animation problem. A "hack" around it is to actually decrease the progress value by 1:
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (int i = 0; i < progressBar1.Maximum; i++) {
progressBar1.Value = i;
progressBar1.Value = Math.Max(i - 1, progressBar1.Minimum);
}
label1.Visible = true;
use progressBar1.Refresh:
public partial class dload : Form
{
public dload()
{
InitializeComponent();
}
private void dload_Load(object sender, EventArgs e)
{
label1.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (i = 0; i <= 5000; i++)
{
progressBar1.Value = i;
progressBar1.Refresh();
if (i == 5000)
{
label1.Visible = true;
}
}
}

How can i empty my progressbar after its full

How can i set my progressBar value to 0 if its full when i click the button it loads so fast i cant see anything
my code is
private void button1_Click(object sender, EventArgs e)
{
int i;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
for (i = 0; i <= 100; i++)
{
progressBar1.Value = i;
if (progressBar1.Value == 100)
{
progressBar1.Value = 0;
}
Refresh();
}
}
Is this what you mean?
private async void button1_Click(object sender, EventArgs e)
{
int i;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
for (i = 0; i <= 100; i++)
{
progressBar1.Value = i;
}
await Task.Delay(2000);
if (progressBar1.Value == 100)
{
progressBar1.Value = 0;
}
}
Edit this will now wait 2 seconds until it sets it to empty so you can see that the progress bar does increment to 100.
Your code does exactly what you require.
You may should add a sleep to see something.
private void button1_Click(object sender, EventArgs e)
{
if(IWantToClearTheProgressbarBeforeWork == true)
progressBar1.Value = 0;
int i;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
for (i = 0; i <= 100; i++)
{
progressBar1.Value = i;
Thread.Sleep(100); // only for testing. Blocks your thread.
}
if(IWantToClearTheProgressbarImediatelyAfterWorkIsDone == true)
progressBar1.Value = 0;
}

Asynchronous Displaying in Windows Form Application c#

I don't think the following question is rarely seen. But since I don't know how to search for the right answer, so I'm still stuck on it.
I have a label in the form and I want to show some words simultaneously
public string[] words = new string[]{"add", "ado", "age", "ago", "aid", "ail", "aim", "air", "and", "any", "ape", "apt", "arc", "are", "ark", "arm",
"art", "ash", "ask", "auk", "awe", "awl", "aye", "bad", "bag", "ban", "bat", "bee", "boa", "ear", "eel", "eft",
"far", "fat", "fit", "lee", "oaf", "rat", "tar", "tie"};
private async void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 39; i++)
{
label1.Text = words[i];
Thread.Sleep(100);
}
}
The label just show "eft" and won't show anything before "for" is complete.
Ideally you should be using a System.Windows.Forms.Timer to update - otherwise you are blocking the main thread. However, you can call Form.Refresh to force an update in your loop.
You may use Task.Delay that would not block the UI thread:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
for (var i = 0; i <= 100; i++)
{
((Button) sender).Content = i.ToString();
await Task.Delay(100);
}
}
Using this solution would not require any extra threads to be created, so it should be more efficient.
Try this
private async void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
label1.Text = i.ToString();
await Task.Run(() => { Thread.Sleep(100); });
}
}
This will work
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 100; i++)
{
Application.DoEvents();
label1.Text = i.ToString();
Thread.Sleep(100);
}
}
call Application.DoEvents() in your code, so your app can handle the other events
You can use System.Threading.Timer:
System.Threading.Timer timer;
int i=-1;
public string[] words = new string[]{"add", "ado", "age", "ago", "aid", "ail", "aim", "air", "and", "any", "ape", "apt", "arc", "are", "ark", "arm",
"art", "ash", "ask", "auk", "awe", "awl", "aye", "bad", "bag", "ban", "bat", "bee", "boa", "ear", "eel", "eft",
"far", "fat", "fit", "lee", "oaf", "rat", "tar", "tie"};
private async void button1_Click(object sender, EventArgs e)
{
timer = new System.Threading.Timer(timer_Tick, null, 0, 100); //Time delay 100
}
private void timer_Tick(Object state)
{
try
{
i++;
this.Invoke((MethodInvoker)delegate
{
label1.Text = words[i];
if (i==words.Length )
timer.Change(Timeout.Infinite, Timeout.Infinite);
});
}
catch (Exception ex)
{
}
finally
{
}
}
ThreadStart safir ;
Thread Nakh;
delegate void kar(string p);
private void button1_Click(object sender, EventArgs e)
{
safir = new ThreadStart(NeveshtanDarBarchasb);
Nakh = Thread(safir);
Nakh.Start();
}
public void NeveshtanDarBarchasb()
{
for (int i = 0; i <= 39; i++)
{
Benevis(I.ToString());
Thread.Sleep(100);
}
}
public void Benevis(string p)
{
if( lbl.InvokeRequired)
{
kar k= new kar(Benevis);
Invoke(k,new object[]{p};
}
else
{
label1.Text = p;
}
}

Updating array of labels from backgroundworkers

I am trying to update an array of Labels which are on a form from a backgroundworker. Here is my code:
for (int i = 0; i < 6; i++)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
arrLabel[i].Text = values[i].ToString();
});
}
else
{
arrLabel[i].Text = values[i].ToString();
}
}
This does not work, but if I try to change text property of each label instead of the array, it works. How can I fix this? Also is there a shorter/better way of updating form controls from backgroundworkers than what I am doing for every single control on my form?
Edit: here is how I defined the array:
private Label[] arrLabel = new Label[6];
and here is the function that I call to assign the array:
private void makeLabelArrays()
{
for (int i = 0; i < 6; i++)
{
arrLabel[i] = (Label)Groupbox1.Controls["label" + (i + 1).ToString()];
}
}
I'm assuming what some of your code looks like; I may be wrong.
You can use the ReportProgress() method to send two pieces of information back to the UI thread - the percentage of completeness (doesn't really apply in your case so I specified 0) and some piece of data (any object you want, just a number in this case).
Then you can get the data in the ProgressChanged event and execute code that touches the UI.
private List<Label> arrLabel = new List<Label>();
private List<string> values = new List<string>();
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var bw = (BackgroundWorker)sender;
for (int i = 0; i < 6; i++)
bw.ReportProgress(0, i);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var currentIndex = Convert.ToInt32(e.UserState);
arrLabel[currentIndex].Text = values[0].ToString();
}
Make sure you enable reporting progress, as it's disabled by default.
backgroundWorker1.WorkerReportsProgress = true;
try the following
private delegate void delegateAssignText();
public void AssignText()
{
if (this.InvokeRequired)
{
Invoke(new delegateAssignText(AssignText));
return;
}
for (int i = 0; i < 6; i++)
{
arrLabel[i].Text = values[0].ToString();
}
}

Report progress inside for loop

I am calling this code inside a for loop and I need to do this since progress depends on this for loop value.
bgworker1.ReportProgress(k * count);
But I receive an exception:
this operation has already had operation completed called on it and further calls are illegal
How can I solve this??
Edit:
private void bgworker1_DoWork(object sender, DoWorkEventArgs e)
{
for (k = 1; k <= tcount; k++)
{
bgworker1.ReportProgress(k * count);
}
}
private void bgworker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void bgworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bgworker1.ReportProgress(k * count);
}
One way you can tackle this is reporting progress in a exclusive for-loop for this only task, like this
private void bgworker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 100; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
//Insert your logic HERE
worker.ReportProgress(i * 1);
}
}
}

Categories