问题
My Solution:
So I managed to find another tutorial http://www.codeproject.com/KB/dotnet/Yet_Another_Splash_Screen.aspx and the sourcecode seemed to make more sense to me. Here is the code i'm using now. Main()
is left untouched.
Splash.cs
`
public partial class Frm_Splash : Form { delegate void ProgressDelegate(int percent); delegate void SplashShowCloseDelegate();
/// <summary> /// To ensure splash screen is closed using the API and not by keyboard or any other things /// </summary> bool CloseSplashScreenFlag = false; /// <summary> /// Base constructor /// </summary> /// public Frm_Splash() { InitializeComponent(); progress_Splash.Show(); this.ClientSize = this.BackgroundImage.Size; } public void ShowSplashScreen() { if (InvokeRequired) { // We're not in the UI thread, so we need to call BeginInvoke BeginInvoke(new SplashShowCloseDelegate(ShowSplashScreen)); return; } this.Show(); Application.Run(this); } /// <summary> /// Closes the SplashScreen /// </summary> public void CloseSplashScreen() { if (InvokeRequired) { // We're not in the UI thread, so we need to call BeginInvoke BeginInvoke(new SplashShowCloseDelegate(CloseSplashScreen)); return; } CloseSplashScreenFlag = true; this.Close(); } /// <summary> /// Update text in default green color of success message /// </summary> /// <param name="Text">Message</param> public void Progress(int percent) { if (InvokeRequired) { // We're not in the UI thread, so we need to call BeginInvoke BeginInvoke(new ProgressDelegate(Progress), new object[] { percent }); return; } // Must be on the UI thread if we've got this far progress_Splash.Value = percent; // Fade in the splash screen - looks pro. :D if (percent < 10) this.Opacity = this.Opacity + .15; } /// <summary> /// Prevents the closing of form other than by calling the CloseSplashScreen function /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SplashForm_FormClosing(object sender, FormClosingEventArgs e) { if (CloseSplashScreenFlag == false) e.Cancel = true; } }`
Form1.cs
public partial class Frm_Main : Form { Frm_Splash frm_Splash = new Frm_Splash(); public Frm_Main() { this.Hide(); Thread splashthread = new Thread(new ThreadStart(frm_Splash.ShowSplashScreen)); splashthread.IsBackground = true; splashthread.Start(); InitializeComponent(); CenterToScreen(); } private void Frm_Main_Load(object sender, EventArgs e) { if (PassedAll() == true) FillMovieLB(); if (FillMovieProgress == 100) { //Throw in this sleep so the user can see the progress bar reach all the way to the end. Thread.Sleep(1000); this.Show(); frm_Splash.CloseSplashScreen(); this.Activate(); } }
Original Question
G'day all,
I'm very new to programming in C# and i'm having a problem with the http://www.codeproject.com/KB/cs/prettygoodsplashscreen.aspx tutorial and implementing it within my application. I'm finding it a little difficult to understand what the problem is. I know there is alot of stuff about getting this splash screen to work but I can't get my head around it.
When I start the program, the Frm_Main
will display, you can see the listbox
being populated, because i've placed it in BackgroundWorker.DoWork()
, and then afterwards my frm_Splash
will show after the work is done. Obviously, the way it should be working is, frm_Splash
will show during the work being done on Frm_Main
, and the progress bar will show the progress of the loading (this part I haven't implemented yet).
Edit: I may not have been clear, but the question is: How can I get my splashscreen to display while the work is being done and before the main form is displayed?
Thanks everybody. :)
Here is my code:
static Frm_Splash frm_Splash = new Frm_Splash();
public delegate void ShowFormDelegate();
public void ShowForm()
{
frm_Splash.Show();
}
public Frm_Main()
{
InitializeComponent();
CenterToScreen();
if (PassedAll() == true)
{
back_loadprog.RunWorkerAsync();
}
}
private void back_loadprog_DoWork(object sender, DoWorkEventArgs e)
{
Invoke(new ShowFormDelegate(ShowForm));
Invoke(new FillMovieLBDelegate(FillMovieLB));
}
回答1:
Here, have some code... Works for me.
Splash Form:
namespace Screens.Forms
{
public partial class Splash : DevExpress.XtraEditors.XtraForm
{
public Splash()
{
InitializeComponent();
}
string RandomLoadingMessage()
{
string[] lines ={
"Pripremam warp pogon",
"Moj drugi ekran za učitavanje je brži, probaj njega",
"Verzija programa koju imam u testiranju imala je smiješnije poruke"
};
return lines[new Random().Next(lines.Length)];
}
public void RandomizeText()
{
lblMessage.Text = RandomLoadingMessage();
}
private void Splash_Load(object sender, EventArgs e)
{
RandomizeText();
}
private static Splash _splash;
private static bool _shouldClose;
static void ThreadFunc()
{
_splash = new Splash();
_splash.Show();
while (!_shouldClose)
{
Application.DoEvents();
Thread.Sleep(100);
if (new Random().Next(1000) < 10)
{
_splash.Invoke(new MethodInvoker(_splash.RandomizeText));
}
}
for (int n = 0; n < 18; n++)
{
Application.DoEvents();
Thread.Sleep(60);
}
if (_splash != null)
{
_splash.Close();
_splash = null;
}
}
static public void ShowSplash()
{
_shouldClose = false;
Thread t = new Thread(ThreadFunc);
t.Priority = ThreadPriority.Lowest;
t.Start();
}
internal static void RemoveSplash()
{
_shouldClose = true;
}
internal static void ShowSplash(List<string> fromTwitterMessages)
{
ShowSplash();
}
}
}
Show it with:
Splash.ShowSplash();
Do the work you need, then when done:
Splash.RemoveSplash();
回答2:
You need to take this a step further back to your Main()
function of the application.
In general you could do this:
- Create a
ManualResetEvent
or betterManualResetEventSlim
if you are on .NET 4 - Start a new thread displaying your SplashScreen, use
Application.Run
- In your SplashScreen you should create a time which polls the created
ManualResetEvent
frequently, a nice animation could be placed here also - If the event is set you should close the form
- Back in your
Main()
do your stuff like creating forms etc. - When finish set the event, so that the SplashScreen can be closed
- To be sure that your
MainForm
is not shown before your SplashScreen is closed you can use another event
来源:https://stackoverflow.com/questions/6692115/cross-thread-cross-form-display-a-splash-screen-with-a-progress-bar