Introduction
If you have code that needs to execute, and you want the user to wait on it, having a "Please Wait" window is helpful. This example (see full code in attached ZIP file) shows one way to do that.
The window the user sees can have text that is updated during the process (that runs in another thread), an image (you can use the default or provide one of your own programmatically), and you can cancel the process while it is running.
Background
Over the years, I have seen a multitude of all sorts of convoluted ways to do this. Without multithreading, such as in VB6, you could use events and that worked OK, but it was not as responsive as multithreading.
Using the Code
PleaseWaitForm.cs contains the code, which has multiple classes. In short, there is a sealed class with static
methods and those methods create and use a Windows form as the Please Wait form, and execute a specified method on a non-UI thread.
In MainForm.cs, the StartButton
executes this code to bring up the Please Wait window and start the process:
private void StartButton_Click(object sender, EventArgs e)
{
StartButton.Enabled = false;
Boolean KeepWindowOpen = KeepWindowOpenCheckBox.Checked;
PleaseWaitWindow.Show(this.Work2Do, KeepWindowOpen);
StartButton.Enabled = true;
}
Note that PleaseWaitWIndow.Show
is a static
method. The Boolean KeepWindowOpen
tells the Please Wait window whether to stay open after completing the process so the user can read the feedback.
This code is the method actually doing the work, and how it interacts with the Please Wait window.
private void Work2Do(Object sender, PleaseWaitWindowEventArgs e)
{
PleaseWaitForm PWWindow = null;
try
{
if (sender != null)
{
if (sender is PleaseWaitForm)
{
PWWindow = (PleaseWaitForm)sender;
}
}
if (PWWindow != null)
{
PWWindow.Invoke(new PleaseWaitWindow.MethodInvokerDelegate<String>
(PWWindow.SetMessage), "Please Wait while Counting Down ...");
PWWindow.Invoke(new PleaseWaitWindow.MethodInvokerDelegate<String>
(PWWindow.SetDescription), "Counting down from 10" + Environment.NewLine + Environment.NewLine);
for (int i = 10; i > 0; i--)
{
String PWMsg = String.Format("{0}...{1}",
i.ToString(), Environment.NewLine);
if (PWWindow.InvokeRequired)
{
PWWindow.Invoke(new PleaseWaitWindow.MethodInvokerDelegate<String>(PWWindow.AppendDescription), PWMsg);
}
System.Threading.Thread.Sleep(1000);
}
}
}
catch (Exception exUnhandled)
{
Shared.WriteToDebugFile(exUnhandled);
}
}
Points of Interest
We developers have a tendency to confuse how complicated our solutions are with how clever they are. The simpler the solution, the better. Cleverness is really found in simplicity. I would not be surprised if someone takes my code and makes it even simpler without losing any functionality.
History
- 04/28/2014 JDJ Genesis
- 04/29/2014 JDJ Updated code in ZIP file to rename Please Wait Form's Cancel button, make sure that button is disabled when the process is done, and add code for the Please Wait form's progress bar that I forgot to do.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.