C# 实现启动欢迎界面的方法

从别人那抄的,保存好!

方法一:

第一步主程序启动主窗体(这里表示为 form1)
如下:
    static class Program
    {
        /// <summary>
        /// 
应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
第二步主窗体( form1) 中的 _Load 事件中启动欢迎界面 (SplashForm)
如下:
        private void Form1_Load(object sender, EventArgs e)
        {
            //
启动窗体
            SplashForm MySplashForm = new SplashForm ();
            MySplashForm.ShowDialog();
        }
第三步欢迎界面中控制界面的显示方式并使用 timer 控制欢迎界面的消失时间 (实际中往往是读取系统需要的配置信息后消失)
如下:
        private void Form2_Load(object sender, EventArgs e)
        {
            //
设置启动窗体
            this.FormBorderStyle = FormBorderStyle.None;
            this.BackgroundImage = Image.FromFile("test.jpg");
            this.timer1.Start();
            this.timer1.Interval = 10000;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            //...........
读取系统配置

            //关闭启动窗体
            this.Close();
        }
        private void SplashForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            //
关闭定时器
            this.timer1.Stop();
        }

 

第二篇

如果程序在装载时需要进行较长时间的处理,最好使用启动画面,一方面美化程序,一方面可以不使用户面对着一片空白的程序界面。
我手头上一个小项目主界面启动时需要检查用户文件及运行环境是否有效,需要一段时间处理,因此想到要添加一个启动画面,在网上搜了一阵,发现下面两个方案:

1
、用C#给程序加启动画面并只允许一个应用程序实例运行
http://www.zahui.com/html/14/36790.htm
2
HOW TO:溅射屏幕(Splash Screen),也叫程序启动画面的制作(.NET2003)
http://lzmtw.cnblogs.com/archive/2005/10/31/265782.html

第一个方案在实现与界面分离上做得不够好,启动界面(一个窗体)依赖于特定窗体,主窗体还必须添加一个PreLoad方法完成装载任务,只能在代码级重用。而且那个只允许一个实例的写法也太....

第二个方案框架很好,但细微处理可能存在一点问题,需要判断主窗体的WindowState,整个代码也较复杂。

我改动了一下,基本结构仿照第二个方案。

功能:为程序添加启动界面,显示启动界面的同时加载主窗体,主窗体加载完毕后关闭启动界面,显示主窗体。启动画面停留的时间是设定的时间和主窗体装载所需时间两个的最大值。启动画面在另一个线程上运行。
plus:
我的水平还很差,见笑。

程序代码如下:

//
启动窗体虚基类,继承自ApplicationContext
using System.Windows.Forms;
using System.Threading;
using System;

//
启动画面虚基类,启动画面会停留一段时间,该时间是设定的时间和主窗体构造所需时间两个的最大值
public   private Form _SplashScreenForm;//
启动窗体
    private Form _PrimaryForm;//
主窗体
    private System.Timers.Timer _SplashScreenTimer;
    private int _SplashScreenTimerInterVal = 5000;//
默认是启动窗体显示5
    private bool _bSplashScreenClosed = false;
    private delegate void DisposeDelegate();//
关闭委托,下面需要使用控件的Invoke方法,该方法需要这个委托

    public SplashScreenApplicationContext()
    {
        this.ShowSplashScreen();//
这里创建和显示启动窗体
        this.MainFormLoad();//
这里创建和显示启动主窗体
    }

    protected abstract void OnCreateSplashScreenForm();

    protected abstract void OnCreateMainForm();

    protected abstract void SetSeconds();

    protected Form SplashScreenForm 
    {
        set 
        {
            this._SplashScreenForm = value;
        }
    }

    protected Form PrimaryForm 
    {//
在派生类中重写OnCreateMainForm方法,在MainFormLoad方法中调用OnCreateMainForm方法
        //  ,
在这里才会真正调用Form1(主窗体)的构造函数,即在启动窗体显示后再调用主窗体的构造函数
        //       
        set 
        {
            this._PrimaryForm = value;
        }
    }

    protected int SecondsShow 
    {//
未设置启动画面停留时间时,使用默认时间
        set 
        {
            if (value != 0) 
            {
                this._SplashScreenTimerInterVal = 1000 * value;
            }
        }
    }

    private void ShowSplashScreen()
    {
        this.SetSeconds();
        this.OnCreateSplashScreenForm();
        this._SplashScreenTimer = new System.Timers.Timer(((double)(this._SplashScreenTimerInterVal)));
        _SplashScreenTimer.Elapsed += new System.Timers.ElapsedEventHandler(new System.Timers.ElapsedEventHandler(this.SplashScreenDisplayTimeUp));

        this._SplashScreenTimer.AutoReset = false;
        Thread DisplaySpashScreenThread = new Thread(new ThreadStart(DisplaySplashScreen));

        DisplaySpashScreenThread.Start();
    }

    private void DisplaySplashScreen()
    {
        this._SplashScreenTimer.Enabled = true;
        Application.Run(this._SplashScreenForm);
    }

    private void SplashScreenDisplayTimeUp(object sender, System.Timers.ElapsedEventArgs e)
    {
        this._SplashScreenTimer.Dispose();
        this._SplashScreenTimer = null;
        this._bSplashScreenClosed = true;
    }

    private void MainFormLoad()
    {
        this.OnCreateMainForm();

        while (!(this._bSplashScreenClosed)) 
        {
            Application.DoEvents();
        }

        DisposeDelegate SplashScreenFormDisposeDelegate = new DisposeDelegate(this._SplashScreenForm.Dispose );
        this._SplashScreenForm.Invoke(SplashScreenFormDisposeDelegate);
        this._SplashScreenForm = null;    


        //
必须先显示,再激活,否则主窗体不能在启动窗体消失后出现
        this._PrimaryForm.Show();
        this._PrimaryForm.Activate();

        this._PrimaryForm.Closed += new EventHandler(_PrimaryForm_Closed);

    }

    private void _PrimaryForm_Closed(object sender, EventArgs e)
    {
        base.ExitThread();
    }
}

使用方法:定义一个启动类,应用程序从启动类启动,该类会使用继承自启动窗体虚基类的一个启动窗体类,在该类中定义启动窗体和主窗体。启动窗体和主窗体的代码略去,注意要删除机器生成的窗体代码的Main方法部分。

    public class StartUpClass
    {
        [STAThread]
        static void Main() 
        {
            Application.Run(new mycontext());
        }
    }

    //
启动窗体类(继承自启动窗体虚基类),启动画面会停留一段时间,该时间是设定的时间和主窗体构造所需时间两个的最大值
      {
        protected override void OnCreateSplashScreenForm()
        {
            this.SplashScreenForm = new FormStart();//
启动窗体
        }

        protected override void OnCreateMainForm()
        {
            this.PrimaryForm = new FormMain();//
主窗体
        }

        protected override void SetSeconds()
        {
            this.SecondsShow = 2;//
启动窗体显示的时间()
        }
    }