Closing a 'form' from another 'form'
I've developed an application where I am using windows form as splash screen. After displaying splash screen, I've created a new thread to trigger new form. Now I want to close 开发者_如何学Csplash screen just after my form has been displayed.
I've googled my query, many discussions but couldn't find what I want.
Please guide me a little.
Thanks.
As long as you have some reference to the first form you call the Close()
method on the other form. So when you create the second form give it a reference to the splash screen. Then attach a handler to the Shown event and call close on the splash screen.
In order to get around the cross thread problem you will need to create a method called something like ThreadSafeClose and define that as below. Then call that method instead of .Close()
public void ThreadSafeClose() {
if(this.InvokeRequired) {
this.Invoke(new MethodInvoker(this.Close));
}
}
In order to close the form you need to have a link to this form. The easiest way to do so is to add a new property to the Program
object in your program that is static and available everywhere. Just modify your Program.cs
file to make the Program
class public and to add the appropriate reference:
public static class Program
{
///This is your splash screen
public static Form1 MySplashScreen = new Form1();
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
/// This is how you run your main form
Application.Run(MySplashScreen);
}
}
Then in your form you can easily close your splash screen form using the following syntax:
Program.MySplashScreen.Close();
EDIT: In WinForms there is only one GUI thread, so as long as you perform the closing from within another form it should be safe. Should you want to close the form from a working thread spawned from a GUI, use the following code (this should reference your second form then):
this.Invoke((MethodInvoker)delegate {
Program.MySplashScreen.Close();
});
Normally you don't need a new thread. But once you have it, you can do it by sharing a bool value (name it closeSplash) between the two threads.
Put a timer on the splash form to check the value of closeSplash each second. When closeSplash is true, just call the Close() method of the Splash form.
See this if you choose to close the splash from another thread.
I have a hacky method i use .. may not be the best thing to do though. in the splash screen form declare a static instance of itself.
public static SplashForm splashInstance;
Then in the constructor for the splashform you can assign a value of "this".
SplashForm.splashInstance = this;
You can now call SplashForm.splashInstance.Close() from anywhere within your app.
You do not need a separate thread just to display a "splash screen" in a period of time. In fact, there are better ways you could design your classes to make doing this a whole lot easier to accomplish. Not using a timer here or using separate threads for this is not the proper solution IMHO. I suggest you try doing something like this:
public class SplashScreen : Form
{
// add a timer to your form with desired interval to show
protected override void OnShown(EventArgs e)
{
displayTimer.Start();
base.OnShown(e);
}
private void displayTimer_Tick(object sender, EventArgs e)
{
this.Close();
}
}
public class MainForm : Form
{
protected override void OnLoad(EventArgs e)
{
// splash screen will be shown before your main form tries to show itself
using (var splash = new SplashScreen())
splash.ShowDialog();
base.OnLoad(e);
}
}
精彩评论