Reputation: 6908
I'm writing a program that can take quite a bit to load(5-30 seconds). I'm wanting to have a form that starts with a marquee style progress bar, so that the user knows there's something being done.
public FrmMain()
{
var loading = new FrmLoading();
loading.Show();
InitializeComponent();
// other start up code here
loading.Close()
}
Now, loading
pops up just fine. The problem is that the label and the progress bar show as nothing, and it almost looks like they are crashing. I've looked into the BackgroundWorker
, but, honestly, I don't fully comprehend how to make that work for me. I tried to follow the tutorials and examples at:
But my head just isn't grasping it. Is there any other way to get the form to load properly? Thanks for any and all help.
EDIT
My BackgroundWorker
attempt included me creating a function which performed all the actions that were done in my FrmMain
. So, I had:
public FrmMain()
{
Loading = new FrmLoading();
Loading.Show();
backgroundWorker1.RunWorkerAsync();
}
private void FormLoading()
{
// Initialize and loading elements of the form
InitializeComponent();
}
private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
FormLoading();
}
private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Loading.Close();
}
But I kept getting NullReferenceException
on the backgroundWorker1.RunWorkerAsync();
Upvotes: 0
Views: 940
Reputation: 6908
What I ended up doing may not be elegant, but it accomplished what I needed.
public FrmMain()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
var loading = new FrmLoading();
loading.ShowDialog();
}
private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
DbQuery();
}
private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Loading.Close();
}
This brings up my loading
form so that it has focus and fully loads. Since I called the DoWork
before I called the ShowDialog()
, the BackgroundWorker
continues to work. Once DbQuery()
is done, it calls the BackgroundWorker1RunWorkerCompleted()
, which closes my FrmLoading
and continues on with my program. Thanks to everyone who posted.
Upvotes: 0
Reputation: 27673
Perhaps this will help:
Add a:
Shown += new EventHandler(Form1_Shown);
after your InitializeComponent();
.
And add:
void Form1_Shown(object sender, EventArgs e)
{
Refresh();
}
Also, if you didn't subscribe to the BackgroundWorker1DoWork
event handler in the Designer, you'll have to add:
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
Upvotes: 0
Reputation: 6689
An little-known or often-forgotten framework library is Microsoft.VisualBasic. You can use it with C# apps. Just add a Reference ... and this class. It handles all background worker threading and the rest.
public class MyApplication : WindowsFormsApplicationBase
{
private static MyApplication _application;
public static void Run(Form form)
{
_application = new MyApplication{ MainForm = form };
_application.Run(Environment.GetCommandLineArgs());
}
protected override void OnCreateSplashScreen()
{
this.SplashScreen = new MySplashScreenForm();
}
}
Finally, change the app launch under Program.Main() from:
Application.Run(new Form1());
to
MyApplication.Run(new Form1());
If you aren't familiar, this class also offers more features like Single-Instance Handling that are definitely worth a look.
Upvotes: 1