Reputation: 32861
I basically need to show a wait window to the user. For this i have put two seperate window forms in the application. the first form is the main form with a button. The second one is a empty one with just a label text. On click of the button in Form1 i do the below
Form2 f = new Form2();
f.Show();
Thread.Sleep(2000);
f.Close();
My idea here is to show the wait window to the user for 2 second. But when i do this the Form 2 is not completely loaded because of which the label in it is blank. Please let me know your inputs on this.
Upvotes: 1
Views: 13328
Reputation: 41
Here is a Waiting Box class I use. Here is how you use it:
using WaitingBox;
ShowWaitingBox waiting = new ShowWaitingBox("Title Text","Some Text so the user knows whats going on..");
waiting.Start();
//do something that takes a while
waiting.Stop();
Here is the code for WaitingBox:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WaitingBox
{
public class ShowWaitingBox
{
private class WaitingForm:Form
{
public WaitingForm()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label1 = new System.Windows.Forms.Label();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Controls.Add(this.progressBar1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 2);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(492, 155);
this.tableLayoutPanel1.TabIndex = 0;
//
// label1
//
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(209, 92);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(73, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Please Wait...";
//
// progressBar1
//
this.progressBar1.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.progressBar1.Location = new System.Drawing.Point(22, 37);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(447, 23);
this.progressBar1.TabIndex = 2;
//
// WaitingForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(492, 155);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "WaitingForm";
this.Text = "Working in the background";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WaitingForm_FormClosing);
this.Load += new System.EventHandler(this.WaitingForm_Load);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
}
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.Label label1;
private void WaitingForm_Load(object sender, EventArgs e)
{
progressBar1.Style = ProgressBarStyle.Marquee;
this.BringToFront();
this.CenterToScreen();
}
private void WaitingForm_FormClosing(object sender, FormClosingEventArgs e)
{
}
internal void SetLabel(string p)
{
label1.Text = p;
}
}
private WaitingForm wf = new WaitingForm();
private string title, text;
private Thread waiting;
public bool IsAlive
{
get
{
return waiting.IsAlive;
}
set { }
}
public ShowWaitingBox(string Title, string Text)
{
this.title = string.IsNullOrEmpty(Title) ? "Working in the Background..": Title;
this.text = string.IsNullOrEmpty(Text) ? "Please wait..." : Text;
waiting = new Thread(new ThreadStart(Show));
}
public ShowWaitingBox()
{
waiting = new Thread(new ThreadStart(Show));
}
private void Show()
{
wf.Show();
wf.Text = this.title;
wf.SetLabel(this.text);
while (true) {
wf.Refresh();
System.Threading.Thread.Sleep(50);
}
}
public void Start()
{
waiting.Start();
}
public void Stop()
{
waiting.Abort();
}
}
}
Upvotes: 4
Reputation: 52518
I think you should just use
f.ShowDialog(this);
Then control is returned when f is closed.
By using the sleep, you are blocking the UI thread from updating for 2 seconds. (The thread is asleep).
Upvotes: 0
Reputation: 76001
You can (an always should for UI threads) use Thread.Current.Join(2000) instead of Thread.Sleep(2000).
Upvotes: -1
Reputation: 9258
When yo use Thread.Sleep you will disable the windows message loop and prevent the window from painting itself.
You could force a repaint:
f.Refresh();
Or better yet use a timer with a callback.
Timer t = new Timer();
t.Interval = 2000;
t.Tick += delegate { Close(); t.Stop();};
t.Start();
To prevent users from clicking in the original window you can open the new form as a dialog:
f.ShowDialog();
Upvotes: 2
Reputation: 1500495
You're basically blocking the UI thread.
I suggest that instead, you make your Form2 constructor (or possibly Load event handler) start a timer which will fire two seconds later. When the timer fires, close the form. During those two seconds, the UI thread will be free, so everything will display properly and the user will be able to move the window etc.
Upvotes: 1
Reputation: 494
That's because you probably do some lengthy operation in the same thread (UI thread). You should execute your code in a new thread (see Thread class) or at least call Application.DoEvents periodically from inside your lengthy operation to update the UI.
Upvotes: 3