WinForm界面开发之 启动界面

我们在开发桌面应用程序的时候,由于程序启动比较慢,往往为了提高用户的体验,增加一个闪屏,也就是SplashScreen,好处有:1、让用户看到加载的过程,提高程序的交互响应;2.可以简短展示或者介绍程序的功能或者展示Logo,给客户较深的印象。

本人在开发的共享软件中,对于启动比较慢的程序,也倾向于引入这个控件来展示下,先看看软件启动的时候的效果

中间的那些文字“正在初始化应用程序......”可以根据加载的进度显示不同的内容,当然最好简单扼要了,其他的内容你也可以视需要做相应变化,因为这个是一个Form,你想改变什么就改变什么的。

看看闪屏代码如何使用先,首先我们在入口的Main函数中开始

    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

              
            //登陆界面
            FrmLogin dlg = new FrmLogin();
            dlg.StartPosition = FormStartPosition.CenterScreen;
            if (DialogResult.OK == dlg.ShowDialog())
            {
             
                   SplashScreen.Splasher.Show(typeof(SplashScreen.FrmSplashScreen));

                  Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
                  Application.Run(new FrmMain());
            }


           
        }

        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs ex)
        {
            //LogHelper.Error(ex.Exception);

            string message = string.Format("{0}
操作发生错误,您需要退出系统么?", ex.Exception.Message);
            if (DialogResult.Yes ==MessageBox.Show(message,"系统错误",MessageBoxButtons.YesNo))
            {
                Application.Exit();
            }
        }
    }

上面代码中:SplashScreen.Splasher.Show(typeof(SplashScreen.frmSplash));主要为启动闪屏类代码,

其中 Splasher 这个类当中使用后台线程,反射来实例化窗体,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;

namespace SplashScreen
{
    public class Splasher
    {
        private static Form m_SplashForm = null;
        private static ISplashForm m_SplashInterface = null;
        private static Thread m_SplashThread = null;
        private static string m_TempStatus = string.Empty;

        /// <summary>
        /// Show the SplashForm
        /// </summary>
        public static void Show(Type splashFormType)
        {
            if (m_SplashThread != null)
                return;
            if (splashFormType == null)
            {
                throw (new Exception("splashFormType is null"));
            }

            m_SplashThread = new Thread(new ThreadStart(delegate()
            {
                CreateInstance(splashFormType);
                Application.Run(m_SplashForm);
            }));

            m_SplashThread.IsBackground = true;
            m_SplashThread.SetApartmentState(ApartmentState.STA);
            m_SplashThread.Start();
        }



        /// <summary>
        /// set the loading Status
        /// </summary>
        public static string Status
        {
            set
            {
                if (m_SplashInterface == null || m_SplashForm == null)
                {
                    m_TempStatus = value;
                    return;
                }

                m_SplashForm.Invoke(
                        new SplashStatusChangedHandle(delegate(string str) { m_SplashInterface.SetStatusInfo(str); }),
                        new object[] { value }
                    );
            }

        }

        /// <summary>
        /// Colse the SplashForm
        /// </summary>
        public static void Close()
        {
            if (m_SplashThread == null || m_SplashForm == null) return;

            try
            {
                m_SplashForm.Invoke(new MethodInvoker(m_SplashForm.Close));
            }
            catch (Exception)
            {
            }
            m_SplashThread = null;
            m_SplashForm = null;
        }

        private static void CreateInstance(Type FormType)
        {

            //利用反射创建对象
            object obj = Activator.CreateInstance(FormType);

            m_SplashForm = obj as Form;
            m_SplashInterface = obj as ISplashForm;
            if (m_SplashForm == null)
            {
                throw (new Exception("Splash Screen must inherit from System.Windows.Forms.Form"));
            }
            if (m_SplashInterface == null)
            {
                throw (new Exception("must implement interface ISplashForm"));
            }

            if (!string.IsNullOrEmpty(m_TempStatus))
                m_SplashInterface.SetStatusInfo(m_TempStatus);
        }


        private delegate void SplashStatusChangedHandle(string NewStatusInfo);

    }
}

为了增加启动界面的说明,在启动界面上增加了一个文字接口,可以在外部来修改启动界面上的说明:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SplashScreen
{
    /// <summary>
    /// interface for Splash Screen
    /// </summary>
    public interface ISplashForm
    {
        void SetStatusInfo(string NewStatusInfo);
    }
}

然手在闪屏的窗体上继承接口,并实现相关的接口代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SplashScreen
{
    public partial class FrmSplashScreen : Form,ISplashForm
    {
        public FrmSplashScreen()
        {
            InitializeComponent();
        }

        //实现接口方法,主要用于接口的反射调用
        #region ISplashForm

        void ISplashForm.SetStatusInfo(string NewStatusInfo)
        {
            lbStatusInfo.Text = NewStatusInfo;
        }

        #endregion
    }
}

然后程序在点击“登录”按钮后,就可以在主界面上做闪屏界面等待了,frmMain窗体代码:

namespace SplashScreen
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();

            System.Threading.Thread.Sleep(800);
            Splasher.Status = "正在展示相关的内容......";
            System.Threading.Thread.Sleep(800);

            //.......此处加载耗时的代码

            Splasher.Status = "初始化完毕............";
            System.Threading.Thread.Sleep(800);

            Splasher.Close();

        }
    }
}
原文地址:https://www.cnblogs.com/gzskys/p/5661302.html