In Desktop application how to create popup progress bar - c#

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

Related

Unable to use WebBrowser Control inside a form that is Loaded from background Worker?

I have a windows form application with Two forms, Login and Account
In the Login form, i have backgroundWorker1
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// doing some heavy work ...
Account acc = new Account(entered_username, entered_password, true);
acc.ShowDialog();
acc.Dispose();
}
//....
And Button1
//...
private void Button1_Click(object sender, System.EventArgs e)
{
showOrHideLoading();
backgroundWorker1.RunWorkerAsync();
}
//...
When i click on button1, the Account form appears correctly but after adding a WebBrowser
Control to the Account form, the application doesn't work as expected, and when i click on Button1, nothing happens!
Is there any limitation of using WebBrowser Control with BackgroundWorker ?
I need to display a link (to facebook like button) using WebBrowser, is there an alternative way to display html content inside Windows Forms Application without using WebBrowser control.
Unless you have a good reason, try to always keep UI on the same thread.
Put your "heavy work" in the background thread and display a progress dialog or whatever.
Once that completes, THEN launch the web browser form.

How can I use backgroundworker in my browser?

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

WinForms programming - Modal and Non-Modal forms problem

I have a problem with modality of the forms under C#.NET. Let's say I have main form #0 (see the image below). This form represents main application form, where user can perform various operations. However, from time to time, there is a need to open additional non-modal form to perform additional main application functionality supporting tasks. Let's say this is form #1 in the image. On this #1 form there might be opened few additional modal forms on top of each other (#2 form in the image), and at the end, there is a progress dialog showing a long operation progress and status, which might take from few minutes up to few hours. The problem is that the main form #0 is not responsive until you close all modal forms (#2 in the image). I need that the main form #0 would be operational in this situation. However, if you open a non-modal form in form #2, you can operate with both modal #2 form and newly created non modal form. I need the same behavior between the main form #0 and form #1 with all its child forms. Is it possible? Or am I doing something wrong? Maybe there is some kind of workaround, I really would not like to change all ShowDialog calls to Show...
Image http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png
Modal forms do exactly what "modal" means, they disable all other windows in the app. That's rather important, your program is in a somewhat perilous state. You've got a chunk of code that is waiting for the dialog to close. Really Bad Things could happen if those other windows were not disabled. Like the user could start the modal dialog again, now your code is nested twice. Or she could close the owner window of the dialog, now it suddenly disappears.
These are the exact kind of problems you'd run into if you call Application.DoEvents() inside a loop. Which is one way to get a form to behave modal without disabling other windows. For example:
Form2 mDialog;
private void button1_Click(object sender, EventArgs e) {
mDialog = new Form2();
mDialog.FormClosed += (o, ea) => mDialog = null;
mDialog.Show(this);
while (mDialog != null) Application.DoEvents();
}
This is dangerous.
It is certainly best to use modal forms the way they were designed to stay out of trouble. If you don't want a modal form then simply don't make it modal, use the Show() method. Subscribe to its FormClosing event to know that it is about to close:
private void button1_Click(object sender, EventArgs e) {
var frm = new Form2();
frm.FormClosing += new FormClosingEventHandler(frm_FormClosing);
frm.Show();
}
void frm_FormClosing(object sender, FormClosingEventArgs e) {
var frm = sender as Form2;
// Do something with <frm>
//...
}
The first thing that comes to mind would be something like this. You could disable form 1 when you launch form 2 and then have form 1 handle the closed event of the second form to re-enable itself. You would NOT open modal 2 using show dialog.
Now keep in mind, from a user perspective this is going to be quite cumbersome, you might look at doing a MDI application to get all windows inside of a single container.
Your main form will not be responsive until any modal dialogs that are in the same process space are closed. There is not work around for that.
It looks to me like you could use an MDI application setting the Form #0 IsMdiContainer property to true.
Then, you could do something alike:
public partial class Form0 {
public Form0 {
InitializeComponent();
this.IsMdiContainer = true; // This will allow the Form #0 to be responsive while other forms are opened.
}
private void button1_Click(object sender, EventArgs e) {
Form1 newForm1 = new Form1();
newForm1.Parent = this;
newForm1.Show();
}
}
Using the ShowDialog() as you stated in your question will make all of the forms Modal = true.
By definition, a modal form is:
When a form is displayed modally, no input (keyboard or mouse click) can occur except to objects on the modal form. The program must hide or close a modal form (usually in response to some user action) before input to another form can occur. Forms that are displayed modally are typically used as dialog boxes in an application.
You can use this property [(Modal)] to determine whether a form that you have obtained from a method or property has been displayed modally.
So, a modal form shall be used only when you require immediate assistance/interaction from the user. Using modal forms otherwise makes believe that you're perhaps running into a wrong direction.
If you do not want your main form to be an MDI container, then perhaps using multithreading is one solution through a simple BackgroundWorker class is the key to what you want to achieve. Thus, it looks to me like a design smell...
What is it you want to do, apart of making your main form responsive, etc.
What is it you have to do?
Explaining what you have to do, we might be able to guide you altogether into the right, or at least perhaps better, direction.
Actually the answer is very simple. Try
newForm.showDialog();
This will open a new form, while the parent one is inaccessible.

How to Redraw or Refresh a screen

I am working on a wpf application. Here I need to use System.Windows.Forms.FolderBrowserDialog in my Wpf application.
System.Windows.Forms.FolderBrowserDialog openFolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
openFolderBrowser.Description = "Select Resource Path:";
openFolderBrowser.RootFolder = Environment.SpecialFolder.MyComputer;
if (openFolderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
//some logic
openFolderBrowser.Dispose();
}
I launch a FolderBrowserDialog, select a Folder and click OK, and then I launch another System.Windows.Forms.FolderBrowserDialog, My problem is when I select a Folder and click OK in this FolderBrowserDialog, the shadow of FolderBrowserDialog remains on the screen(means my screen doesn't refresh). I need to minimize or resize it in order to remove the shadow of FolderBrowserDialog. How can I solve this issue?
Any help plz?
Edit:
I found the solution. I called OnRender method on my wpf Window and it worked for me. It redraws everythign on the screen.
You can call InvalidateVisual method to refresh UI.
on a form code
Update();
refreshes screen and updates ui.
We are using winforms so Update() is a basic function that redraws the window content. so you may use it directly from a form. The basic usage could be a timer which updates a label on a screen. when timer ticks you update the label:
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 1000; // specify interval time as you want
t.Tick += new EventHandler(timer_Tick);
t.Start();
void timer_Tick(object sender, EventArgs e)
{
label1.text = DateTime.Now.ToString("h:mm:ss"));
Update(); //this will refresh the form and label's text is updated.
}
otherwise label1.text will never change.

Why is Form.Refresh() not working?

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();

Categories

Resources