码迷,mamicode.com
首页 > Windows程序 > 详细

C#: 启动画面设计

时间:2015-10-11 22:49:39      阅读:457      评论:0      收藏:0      [点我收藏+]

标签:

Windows Form经常会在启动主界面的时候预先有启动画面,这也是因为用户体验的需要,用户知道已经启动application,而不是在load resource的时候等待。因此这里不能用单线程的思路,单单只是设计一个界面而已,而需要在splash画面的时候同时Load resource。那么这个技术有两个线程,一个是splash画面,二是load resource。搜了一些资料,下面进行一些总结:

技术分享
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Windows.Forms;
 5 using System.Threading;
 6 
 7 namespace WindowsTest
 8 {
 9     static class Program
10     {
11         /// <summary>
12         /// 应用程序的主入口点。
13         /// </summary>
14         [STAThread]
15         static void Main()
16         {
17             Application.EnableVisualStyles();
18             Application.SetCompatibleTextRenderingDefault(false);
19 
20             Thread thUI = new Thread(new ThreadStart(ShowSplashWindow));
21             thUI.Name = "Splash UI";
22             thUI.Priority = ThreadPriority.Normal;
23             thUI.Start();
24 
25             Thread th = new Thread(new ThreadStart(LoadResources));
26             th.Name = "Resource Loader";
27             //th.Priority = ThreadPriority.Highest;
28             th.Priority = ThreadPriority.Normal;
29             th.Start();
30             th.Join();
31 
32             if (splashForm != null)
33             {
34                 splashForm.Invoke(new MethodInvoker(delegate { splashForm.Close(); }));
35             }
36 
37             thUI.Join();
38             Application.Run(new MainForm());
39         }
40 
41         public static SplashForm splashForm
42         {
43             get;
44             set;
45         }
46 
47         private static void ShowSplashWindow()
48         {
49             splashForm = new SplashForm();
50             Application.Run(splashForm);
51         }
52 
53         private static void LoadResources()
54         {
55             for (int i = 1; i <= 8; i++)
56             {
57                 if (splashForm != null)
58                 {
59                     splashForm.Invoke(new MethodInvoker(delegate { splashForm.label1.Text = "Loading some things... " + DateTime.Now.ToString(); }));
60                 }
61                 Thread.Sleep(1000);
62             }
63             splashForm.Invoke(new MethodInvoker(delegate { splashForm.label1.Text = "Done. " + DateTime.Now.ToString(); }));
64         }
65     }
66 }
View Code

这段代码的问题在于画面启动完主界面是最小化了,不解为何如此

 

 

http://www.sufeinet.com/forum.php?mod=viewthread&action=printable&tid=2697

这里的代码比较成熟了,我做了一些小小的改变。用ApplicationContext来解决splash form和main form之间的转换,而在Program的类的InitApp function里如果要改变splash from的label1则需要Invoke来异步调用SplashFrom的PrintMsg function,否则会卡卡面。

Program.cs:

技术分享
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Windows.Forms;
 5 using System.Threading;
 6 
 7 namespace WindowsTest
 8 {
 9     static class Program
10     {
11         /// <summary>
12         /// 应用程序的主入口点。
13         /// </summary>
14         [STAThread]
15         static void Main()
16         {
17             Application.EnableVisualStyles();
18             Application.SetCompatibleTextRenderingDefault(false);
19 
20             MyApplicationContent appContent = new MyApplicationContent(new MainForm(), new SplashForm());
21             Application.Run(appContent);
22         }
23 
24         //模拟耗时操作,这里假调程序需要访问网络来实现登录验证
25         //这是一个耗时操作,我们需要在执行的过程中,向用户实时显示一些信息
26         //那么,多线程是唯一的解决方案,在主线程执行这些,界面会死掉的
27         public static void InitApp(Object parm)
28         {
29             SplashForm startup = parm as SplashForm;
30             startup.Invoke(new UiThreadProc(startup.PrintMsg), "正在初始化...");
31             Thread.Sleep(100);
32             startup.Invoke(new UiThreadProc(startup.PrintMsg), "正在验证用户身份信息...");
33             Thread.Sleep(2000);
34             startup.Invoke(new UiThreadProc(startup.PrintMsg), "用户身份验证成功。");
35             Thread.Sleep(500);
36             startup.Invoke(new UiThreadProc(startup.PrintMsg), "正在登录...");
37             Thread.Sleep(2000);
38             bool loginSuccess = true;
39             //这里可以根据执行的结果判断,如果登录失败就退出程序,否则显示主窗体
40             if (loginSuccess)
41             {
42                 startup.Invoke(new UiThreadProc(startup.PrintMsg), "登录成功,欢迎使用!");
43                 Thread.Sleep(100);
44                 startup.Invoke(new UiThreadProc(startup.CloseForm), false);
45             }
46             else
47             {
48                 startup.Invoke(new UiThreadProc(startup.CloseForm), true);
49             }
50         }
51     }
52 
53     public delegate void UiThreadProc(Object o);
54     //WinForm里,默认第一个创建的窗体是主窗体,所以需要用应用程序域来管理
55     public class MyApplicationContent : ApplicationContext
56     {
57         private Form realMainForm;
58 
59         public MyApplicationContent(Form mainForm, Form flashForm)
60             : base(mainForm)
61         {
62             this.realMainForm = mainForm;
63             this.MainForm = flashForm;
64         }
65 
66         protected override void OnMainFormClosed(object sender, EventArgs e)
67         {
68             if (sender is SplashForm)
69             {
70                 SplashForm splashForm = sender as SplashForm;
71 
72                 if (!splashForm.Exit)
73                 {
74                     this.MainForm = realMainForm;
75 
76                     realMainForm.Show();
77                 }
78                 else
79                 {
80                     base.OnMainFormClosed(sender, e);
81                 }
82             }
83             else
84             {
85                 base.OnMainFormClosed(sender, e);
86             }
87         }
88     }
89 }
View Code

SplashForm.cs:

技术分享
 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Threading;
10 
11 namespace WindowsTest
12 {
13     public partial class SplashForm : Form
14     {
15         private bool exit;
16  
17         public bool Exit
18         {
19             get { return exit; }
20         }
21  
22         public SplashForm()
23         {
24             InitializeComponent();
25         }
26  
27         //显示文字信息
28         public void PrintMsg(Object msg)
29         {
30             label1.Text = msg.ToString();
31         }
32  
33         //关闭启动窗体,如果需要中止程序,传参数false
34         public void CloseForm(Object o)
35         {
36             this.exit = Convert.ToBoolean(o);
37             this.Close();
38         }
39 
40         private void SplashForm_Load(object sender, EventArgs e)
41         {
42             ThreadPool.QueueUserWorkItem(new WaitCallback(Program.InitApp), this);
43         }
44     }
45 }
View Code

只需要将Program.cs里的InitApp里的Thread.Sleep改成实际的load resource代码即可

C#: 启动画面设计

标签:

原文地址:http://www.cnblogs.com/yingzhongwen/p/4870132.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!