Reputation: 12216
Okay, based on the advice on the answers below I eliminated my thread approach and now my program looks like this: program.cs
static void Main(){
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
FrmWWCShell FrmWWCShell = null;
var splash = new FrmSplash();
splash.SplashFormInitialized += delegate
{
FrmWWCShell = new FrmWWCShell();
splash.Close();
};
Application.Run(splash);
Application.Run(FrmWWCShell);
}
And FrmSplash.cs like this:
public partial class FrmSplash : Form
{
public FrmSplash()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
splashTimer.Interval = 1;
splashTimer.Tick +=
delegate { if (SplashFormInitialized != null) SplashFormInitialized(this, EventArgs.Empty); };
splashTimer.Enabled = true;
}
public event EventHandler SplashFormInitialized;
}
The problem is that it doesn't work at all now. The splash screen pops up for a split second, the marque progress bar never even initializes, and then disappears while I wait the 10 secs for the dll's and Main Form to show up while staring at nothing....
Color me severely confused now!
I implemented a App Loading splash screen that operates on a seperate thread while all of the dll's are loading and the form is getting "Painted." That works as expected. What is strange is that now when the Splash form exits it sends my main Form to the back, if there is anything else open(i.e. Outlook). I start the thread in Program.cs,
static class Program
{
public static Thread splashThread;
[STAThread]
static void Main()
{
splashThread = new Thread(doSplash);
splashThread.Start();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmWWCShell());
}
private static void doSplash()
{
var splashForm = new FrmSplash();
splashForm.ShowDialog();
}
}
And then I end it once my FrmSearch_Shown event is fired.
private void FrmSearch_Shown(object sender, EventArgs e)
{
Program.splashThread.Abort();
this.Show();
this.BringToFront();
}
I, as you can see, have tried calling a Show() and/or BringToFront() on FrmSearch and it still "jumps" to the back.
What am I missing?
What else can I try?
Am I doing this so horribly ignorant that it is my process that is causing this?
Should I file for early retirement?
Thanks for any insight!
I tried setting the TopMost Property on my Main Form to TRUE. This keeps my form from hiding but it also keeps the user from looking at any other app. Seems a little narcissistic of me...
Upvotes: 1
Views: 414
Reputation: 11736
Try calling Application.DoEvents() right after show.
Warning: do not call DoEvents very often, but this is one of those time.
EDIT: Clyde noticed something I did not: you are threading this. Don't run any UI on another thread. Take out the thread, leave in the Application.DoEvents().
Upvotes: 0
Reputation: 8145
First of all, it's very important that UI work is done on the primary application thread. I'm actually kind of surprised that you're not getting more serious errors already by showing the splash screen on a background thread.
Here's a technique I've used:
Use Application.Run on your splash form rather than your "real" form.
In your splash form, have an initialized event:
public event EventHandler SplashFormInitialized
Create a timer that fires in one millisecond, and triggers that event.
Then in your application run method you can load your real form, then close your splash form and do an Application.Run on the real form
var realForm = null;
var splash = new SplashForm();
splash.SplashFormInitialized += delegate {
// As long as you use a system.windows.forms.Timer in the splash form, this
// handler will be called on the UI thread
realForm = new FrmWWCShell();
//do any other init
splash.Close();
}
Application.Run(splash); //will block until the splash form is closed
Application.Run(realForm);
The splash might include:
overrides OnLoad(...)
{
/* Using a timer will let the splash screen load and display itself before
calling this handler
*/
timer.Interval = 1;
timer.Tick += delegate {
if (SplashFormInitialized != null) SplashFormInitialized(this, EventArgs.Empty);
};
timer.Enabled = true;
}
Upvotes: 5