程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> SplashScreen實現加載數據

SplashScreen實現加載數據

編輯:C#入門知識

背景
對於windows開發人員來說在打開VS開發工具時,總是先呈現一個SplashScreen界面,登上幾秒鐘後才打開VS的主界面。這樣的效果一般是在主界面需要加載大量資源,為避免主界面變成“死”界面,而提供一個友好的Loading畫面。為實現該效果,我們通常在加載主界面Application.Run(new MainForm())之前打開一個SplashScreen窗口,並在SplashScreen窗口中加載數據。

接口WindowsFormsApplicationBase
微軟提供了WindowsFormsApplicationBase類,該類提供了SplashScreen屬性,及OnCreateSplashScreen虛方法的接口。在實現自己的SplashScreen窗口時,主要重載OnCreateSplashScreen方法,並創建一個Form對象,賦值給SplashScreen屬性,並且該類還提供了MinimumSplashScreenDisplayTime屬性,用於設置SplashScreen窗口的呈現時間。當然你可以自己控制SplashScreen窗口的呈現和關閉。

實現Application類
首先我們需要實現WindowsFormsApplicationBase基類SplashScreenApplication,並重新OnCreateSplashScreen方法。代碼如下:

internal sealed class SplashScreenApplication : WindowsFormsApplicationBase {
        public SplashScreenApplication() {
            base.IsSingleInstance = true;
            base.EnableVisualStyles = true;
     base.MinimumSplashScreenDisplayTime = 2000;
        }

        protected override void OnCreateMainForm() {
            this.MainForm = new Form1();
        }

        protected override void OnCreateSplashScreen() {
            this.SplashScreen = new SplashScreenForm();
        }
    }
其中Form1為主窗口,SplashScreenForm為Loading窗口,並設置2000毫秒SplashScreen自動關閉,並試圖打開主窗體。Application會首先執行OnCreateSplashScreen方法,然後執行OnCreateMainForm窗口。需要注意的是,2000毫秒並不是兩個方法的執行的時間間隔,而是主窗體創建2000毫秒後才關閉SplashScreen窗體,並顯示主窗體,這裡的SplashScreenForm不能用於加載數據,因為2000毫秒好就會關閉,我們不能保證SplashScreen可以在2000毫秒吧數據加載完成。

實現加載效果
這裡SplashScreen的目的是加載數據,而不是簡單的友好效果,因此簡單的2000毫秒不能達到我們加載數據的需求。鑒於此,我們需要自己控制SplashScreen界面,當數據加載完成後才能關閉SplashScreen窗口,並顯示主界面。為達到加載數據的效果,這裡會再SpashScreen界面顯示加載數據的過程。代碼如下:

internal sealed class SplashScreenApplication : WindowsFormsApplicationBase {
        public ManualResetEvent resetEvent = new ManualResetEvent(true);

        public SplashScreenApplication() {
            base.IsSingleInstance = true;
            base.EnableVisualStyles = true;
        }

        protected override void OnCreateMainForm() {
            if (resetEvent.WaitOne()) {
                this.MainForm = new Form1();
            }
        }

        protected override void OnCreateSplashScreen() {
            this.SplashScreen = new SplashScreenForm();
        }
    }
WindowsFormsApplicationBase 類是位於Microsoft.VisualBasic.ApplicationServices命名空間下,需要添加Microsoft.VisualBasic.dll引用。為演示加載過程,SplashScreenForm還負責了加載數據:

public partial class SplashScreenForm : Form {
        static string[] Resources = new string[]{
            "Check update.",
            "Updating",
            "Downloading xxx.dll from remote server.",
            "Downloading xxx.config from remote server.",
            "Updated.",
            "Check if the devices pluged in.",
            "Open devices.",
            "Load data from database.",
            "Load file data from remote.",
            "Download necessary files.",
            "Ready"
        };

        public SplashScreenForm() {
            InitializeComponent();
            this.Opacity = 0.8;
            Program.app.resetEvent.Reset();
        }

        private void SplashScreenForm_Load(object sender, EventArgs e) {
            backgroundWorker1.RunWorkerAsync();
        }

        private delegate void run();

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
            float total = 0f;
            float pre = 100f / Resources.Length;

            foreach (string res in Resources) {
                total += pre;
                backgroundWorker1.ReportProgress((int)total, res);
                Thread.Sleep(1000);
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
            this.Invoke(new run(() => {
                label1.Text = e.UserState.ToString();
                progressBar1.Value = e.ProgressPercentage;
            }));
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            this.Invoke(new run(() => {
                label1.Text = "Inititalization finished.";
                progressBar1.Value = 100;
               
            }));

            Thread.Sleep(1000);

            this.Invoke(new run(() => {
                this.Close();
                Program.app.resetEvent.Set();
            }));
        }
    }
程序入口:
static class Program {
        public static SplashScreenApplication app = new SingleInstanceApplication();
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args) {
            app.Run(args);
        }
    }
運行效果
運行效果如下圖:

 

其他
另外我們的加載數據過程只在SplashScreen窗口中,那麼MainForm就不能加載太耗時的資源了,否則關閉SplashScreen窗口後,才開始創建MainForm窗體,就其不到Loading的效果了。如果希望在MainForm中加載數據的,也可以修改代碼,在MainForm中控制SplashScreen的關閉。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved