EDIT 2
Okay, based on the advice on the answers below I eliminated my thread approach and now my program looks like this: program.cs
好的,根据以下答案的建议,我删除了我的线程方法,现在我的程序看起来像这样: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:
和FrmSplash.cs是这样的:
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....
问题是它现在根本不起作用。启动屏幕弹出一瞬间,品牌进度条甚至没有初始化,然后消失,而我等待10秒钟的dll和主窗体出现,同时盯着什么......
Color me severely confused now!
让我现在严重困惑!
ORIGINAL POST--> for reference
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,
我实现了一个App Loading启动屏幕,该屏幕在单独的线程上运行,同时所有的dll都在加载并且表单正在“绘制”。这按预期工作。奇怪的是,现在当Splash表单退出时,如果还有其他任何打开(即Outlook),它会将我的主表单发送到后面。我在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.
然后,一旦我的FrmSearch_Shown事件被触发,我就结束它。
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.
正如你所看到的,我试图在FrmSearch上调用Show()和/或BringToFront(),它仍然“跳”到后面。
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!
感谢您的任何见解!
EDIT 1
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...
我尝试将主表单上的TopMost属性设置为TRUE。这样可以防止我的表单隐藏,但它也会阻止用户查看任何其他应用程序。似乎对我有点自恋......
2 个解决方案
#1
5
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.
首先,在主应用程序线程上完成UI工作非常重要。通过在后台线程上显示启动画面,我真的很惊讶你没有得到更严重的错误。
Here's a technique I've used:
这是我用过的一种技术:
Use Application.Run on your splash form rather than your "real" form.
在您的启动表单上使用Application.Run而不是“真实”表单。
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
然后在您的应用程序运行方法中,您可以加载您的真实表单,然后关闭您的启动表单并在真实表单上执行Application.Run
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;
}
#2
0
Try calling Application.DoEvents() right after show.
尝试在show之后调用Application.DoEvents()。
Warning: do not call DoEvents very often, but this is one of those time.
警告:不要经常调用DoEvent,但这是其中之一。
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().
编辑:克莱德注意到我没有注意到的事情:你正在线程化。不要在另一个线程上运行任何UI。取出线程,留在Application.DoEvents()中。
#1
5
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.
首先,在主应用程序线程上完成UI工作非常重要。通过在后台线程上显示启动画面,我真的很惊讶你没有得到更严重的错误。
Here's a technique I've used:
这是我用过的一种技术:
Use Application.Run on your splash form rather than your "real" form.
在您的启动表单上使用Application.Run而不是“真实”表单。
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
然后在您的应用程序运行方法中,您可以加载您的真实表单,然后关闭您的启动表单并在真实表单上执行Application.Run
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;
}
#2
0
Try calling Application.DoEvents() right after show.
尝试在show之后调用Application.DoEvents()。
Warning: do not call DoEvents very often, but this is one of those time.
警告:不要经常调用DoEvent,但这是其中之一。
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().
编辑:克莱德注意到我没有注意到的事情:你正在线程化。不要在另一个线程上运行任何UI。取出线程,留在Application.DoEvents()中。