I'm trying to create my own web browser for my practice on windows application. So I've make a windows form for web browser. Now I want to use backgroundworker or progressbar to show real process of page loading but I don't know how to do it. I tried with Google but no result for me. So please help me if my question is right to ask about it.
// add progress bar
private ProgressBar progressBar1;
//create event for ProgressChanged
Browser.ProgressChanged += Browser_ProgressChanged;
...
// set progress bar value when ProgressChanged event firing
void Browser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e) {
if (e.MaximumProgress > 0) {
int prog = (int)(100 * e.CurrentProgress / e.MaximumProgress);
progressBar1.Value = prog;
}
}
C# Winforms: Using a progress bar with Web Browser Control
Here are some links:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://www.dotnetperls.com/backgroundworker
http://www.codeproject.com/KB/cs/bgworkercomponent.aspx
Related
I have read many answers on this question, and yet I still cannot get this to work. I have a simple C# WinForms app with a timer control. When the timer fires, I have some code do some processing. I want to update a textbox with status during this processing. But the textbox never gets updated until the eventhandler finishes. Please tell me how I can get the textbox to update during the processing.
Here is my code:
My Form:
public Form1()
{
InitializeComponent();
timer1.Interval = 60000;
timer1.Tick += new EventHandler(CheckStatus);
timer1.Start();
}
private void CheckStatus(object Sender, EventArgs e)
{
// Set the caption to the current time.
textBox1.AppendText(DateTime.Now.ToString() + Environment.NewLine);
ProcessStatus();
}
private void ProcessStatus()
{
textBox1.AppendText("Now updated" + Environment.NewLine);
}
If I step through my code, the textbox is not updated until I step out of CheckStatus. (I'm using Visual Studio 2017)
I have tried several things like what is found here: StackOverflow
When the timer ticks it's firing on the GUI thread. While the GUI thread is busy processing (I assume whatever you're doing takes a long time) all other GUI updates will pause.
You can run textBox.Update() to force the update at that point, but that's not considered a best practice.
Instead, you should run your process on a background thread. One option is BackgroundWorker and use the ProgressChanged event to show your updates in your GUI.
I have a Windows Form application in c#.
in my application i have a WebBrowser Control. in my program web browser will upload a file i want to show in my program what percentage of file is uploaded. how can i do this ?
look at web browser ProgressChanged. This event has an argument as WebBrowserProgressChangedEventArgs which holds CurrentProgress property which you can use to show with the progress bar.
WebBrowser1.ProgressChanged += WebBrowser1_ProgressChanged;
private void WebBrowser1_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e) {
ProgressBar1.Value = e.CurrentProgress;
}
I am attempting to add a progress bar (MARQUEE style) in my c# excel add in. The progress bar appears but it does not indicate any progress until the function is finished executing, meaning that it remains frozen.
These are the functions in the Windows Form Class:
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
//run in back thread
backgroundWorker1.ReportProgress(i);
}
}
//call back method
public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
//call back method
public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Value = progressBar1.Maximum;
}
This is how I call the function from the add in button:
private void buttonClicked(object sender, RibbonControlEventArgs e)
{
AddInPlanView.Form1 pBar = new AddInPlanView.Form1();
pBar.Visible = true;
pBar.backgroundWorker1.WorkerReportsProgress = true;
pBar.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(pBar.backgroundWorker1_ProgressChanged);
pBar.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(pBar.backgroundWorker1_DoWork);
pBar.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(pBar.backgroundWorker1_RunWorkerCompleted);
pBar.backgroundWorker1.RunWorkerAsync();
FUNCTIONTORUN();
pBar.Visible = false;
}
My code now attempts to put the progress bar on a background worker. I know I should switch this so that FUNCTIONTORUN() should be on a background worker, but how do I go about doing that? Since it is a marquee progress bar I do not need to update the value of the progress bar at all, it just needs to run until FUNCTIONTORUN() ends. Note that FUNCTIONTORUN() updates the cells of an Excel worksheet.
The progress bar is initialized using the Visual Studio designer. The name of the ProgressBar object in the form class is progressbar1.
to start a marquee style progress bar, type
progressbar1.Style = ProgressBarStyle.Marquee;
progressbar1.MarqueeAnimationSpeed = 100;
to stop the marquee type
progressbar1.MarqueeAnimationSpeed= 0;
Source: http://social.msdn.microsoft.com/forums/en-US/winforms/thread/9e51ad57-988e-4c17-98f0-cd2a8abec503/
FUNCTIONTORUN(); // make your UI thread busy.
System.Windows.Forms.Application.DoEvents(); // might help in this case.
In most of this sort of cases DoEvent doesn't help (according to my experience). So, it's quite difficult to get process bar to work smoothly.
When the Background worker completes just stop the progress bar.
Inside of this function pBar.backgroundWorker1_RunWorkerCompleted just call the Stop function for the progress bar.
I believe you have to put FUNCTIONTORUN() into sepratae thread, and still it's execution call
ReportProgress method, in order to raise backgroundWorker1_ProgressChanged where you can update your porgress bar value. I suppose, as I don't see it in the code provided, you don't call ReportProgress function somewhere in the code.
EDITED: saw ReportProgress function.
So move your function into separate thread and update the value of progress bar into the main thread.
Hope this helps.
Regards.
Your FUNCTIONTORUN() blocks the UI thread.
Spread some System.Windows.Forms.Application.DoEvents() inside your long-running functions to process events (so the UI updates).
This, as mentioned, will update the UI and let the application respond to other events.
You might want to disable the button that triggers this long-running function, or other long-running functions.
You could create an additional background worker with a DoWork that contains the call to your FUNCTIONTORUN() inside of it and a RunWorkerCompleted that makes your bar stop or go invisible. Then, instead of calling FUNCTIONTORUN(), call backGroundWorker2.RunWorkerAsync();
This should prevent the function from freezing your UI. I ran into this issue last summer doing nearly the exact same thing, and fixed it using backgroundworkers.
I work on C# .I want to create a Desktop(not web) application in c#.There i need to popup window like as web.When popup window appear user can not access any control like web loading panel property MODEL=true.My application work flow is:
Popup appear
Event Start
Event Complete
Popup close
Then Perform rest of the application
private void timer1_Tick(object sender, EventArgs e)
{
if (progressBar1.Value >= 200)
{
progressBar1.Value = 0;
GetAllData();//When this Method active .Progress bar show it's //progressing.After complete the work progressbar will hide.How can i measure how much //time does the computer needs to complete this method work.
timer1.Stop();
}
progressBar1.Value += 20;
}
Assuming your popup is a form you can use ShowDialog instead of Show to make the form modal.
I think you are talkin about modal dialog boxes. If you using WPF, read this:
http://msdn.microsoft.com/en-us/library/aa969773.aspx
I'm running a data import, using a Windows form to kick off the import and show progress.
I've got this whole thing so nice and user friendly, with major and minor progress bars and everything... but just one problem... the form refresh keeps going AWOL.
I have a call to Form.Refresh() every time I update my labels/progress bars, and it usually starts off working. But if ever I need to break into debug mode, just to hand-hold the import a bit, the Refresh() call stops working, and sometimes even if I'm running without Debug mode, at some unpredictable point the same thing happens: the labels and progress bars do not get updated, and if you hide the form and reopen it, the form does not repaint at all - it just shows up entirely white.
Why, oh why, does Form.Refresh() stop working, and how can I fix this?
It sounds as if the import runs on the UI thread, which means that this thread is blocked, preventing the form from repainting itself. A better approach would be to use a BackgroundWorker component, do the import in the DoWork event handler and use the ProgressChanged to update the UI.
Example:
private void StartImport()
{
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.RunWorkerAsync();
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// do some work simulating a lenghy process which occasionally
// reports progress with data back to the caller
for (int i = 0; i < 100; i++)
{
Thread.Sleep(200);
backgroundWorker.ReportProgress(i, "Item No " + i.ToString());
}
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
listBox.Items.Add(e.UserState.ToString());
}
Using this approach you will typically not need to call Refresh to force a repaint of the form.
You may want to change your code into using BeginUpdate and EndUpdate, like so:
Control.BeginUpdate();
// Do something to the control, e.g. add items or whatnot
Control.EndUpdate();
This way Refresh shouldn't be necessary.
AFAIK constantly calling Refresh is really a hack and should be avoiding, as it stresses the CPU quite a bit (it has to refresh everything instead of just the things which are changed).
Edit: If the form starts being white, it seems the drawing code is not been called at all, which indicates it's somewhat not responding.
I'd check the code for anything that can deadlock or otherwisely hang.
You could use observer pattern..in short if anything changes in model observer pattern will make sure that change is visible on form..
google it for some examples..
Depending on what .NET framework you're using, you can use the Task.Run approach:
private void btnShowProgress_Click(object sender, EventArgs e)
{
progressBar1.Value = 0;
Task.Run(() =>
{
for (int i = 0; i <= 100; i++)
{
Thread.Sleep(100);
progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = i; }));
}
});
}
Task.Run info
Using invoke with controls
The solution may not be the best practice but it definitely works for small applications.
In Form1 create a bool to check to see if the form is closed.
public bool formclosed = false
Then in Form2 on the Form Closing Event Handler add
formclosed = true
also in the Form2 after
InitializeComponent();
add
formclosed = false;
In Form1 create a timer.
In the timer1.Tick event handler say
private void timer1_Tick(object sender, EventArgs e)
{
if(formclosed == true)
{
Application.Restart();
}
}
This will restart the application and refresh everything ... I also had my text saved to the Properties.Settings.Default so everytime the application started the default settings would show.
I created an initial version of a Progress control using a BackgroundWorker. The Progress control computed and displayed nice things like Estimated Duration, Estimated Time to Completion. Each statistic was displayed by custom control based on a Label control. The Progress control worked in my production code.
Then I made some changes to the Progress control. I switched from basing my custom statistics controls from Label to Panel. I successfully ran all my tests (using NUnit). Then, I created a Test Windows Forms app. The Progress control successfully worked in the Test Windows Forms app.
When I ran my production Windows app with the updated Progress control it didn't display the statistics.
I tried Thread.Sleep(N), Form.Refresh(). None of those worked to update the statistics.
I eventually called Control.Invalidate() on each Statistic control. The Invalidate caused OnPaint to be called and the control happily updated the display with its specific statistic.
For Each Stat_Obj As Control in Statistics_Controls
Stat_Obj.Invalidate()
Next
You might need to give the window time to redraw itself. I understand you're doing the import in a loop and the loop is running on the main UI thread? Try adding this line to the loop:
Application.DoEvents();