WinForm下的loading框的實現

前言:在項目使用C/S模式狀況下,因爲須要常常進行數據的刷新,若是直接進行刷新,會有一個等待控件重畫的過程,很是的不友好,所以在這裏添加一個loading框進行等待顯示。函數

實現:在通過多方面查詢資料,終因而實現了一個完整的loading框程序,這裏主要解決在屢次點擊查詢按鈕或者加載數據時出現的:執行 CreateHandle() 時沒法調用值 Close()或者沒法訪問已釋放的對象或者在建立窗口句柄以前,不能在控件上調用 Invoke 或 BeginInvoke。這三個問題困擾我好久,最終經過不斷的調試,將其解決,話很少說,直接上代碼。
ui


1.下面類爲loading框幫助類,在實際調用過程當中,使用該類調用相關函數便可。this

 1 class LoadingHelper
 2 {
 3         #region 相關變量定義
 4         /// <summary>
 5         /// 定義委託進行窗口關閉
 6         /// </summary>
 7         private delegate void CloseDelegate();
 8         private static LoaderForm loadingForm;
 9         private static readonly Object syncLock = new Object();  //加鎖使用
10 
11         #endregion
12 
13         private LoadingHelper()
14         {
15 
16         }
17 
18         /// <summary>
19         /// 顯示loading框
20         /// </summary>
21         public static void ShowLoadingScreen()
22         {
23             // Make sure it is only launched once.
24             if (loadingForm != null)
25                 return;
26             Thread thread = new Thread(new ThreadStart(LoadingHelper.ShowForm));
27             thread.IsBackground = true;
28             thread.SetApartmentState(ApartmentState.STA);
29             thread.Start();
30 
31         }
32 
33         /// <summary>
34         /// 顯示窗口
35         /// </summary>
36         private static void ShowForm()
37         {
38             if (loadingForm != null)
39             {
40                 loadingForm.closeOrder();
41                 loadingForm = null;
42             }
43             loadingForm = new LoaderForm();
44             loadingForm.TopMost = true;
45             loadingForm.ShowDialog();
46         }
47 
48         /// <summary>
49         /// 關閉窗口
50         /// </summary>
51         public static void CloseForm()
52         {
53             Thread.Sleep(50); //可能到這裏線程還未起來,因此進行延時,能夠確保線程起來,完全關閉窗口
54             if (loadingForm != null)
55             {
56                 lock (syncLock)
57                 {
58                     Thread.Sleep(50);  
59                     if (loadingForm != null)
60                     {
61                         Thread.Sleep(50);  //經過三次延時,確保能夠完全關閉窗口
62                         loadingForm.Invoke(new CloseDelegate(LoadingHelper.CloseFormInternal));
63                     }
64                 }
65             }
66         }
67 
68         /// <summary>
69         /// 關閉窗口,委託中使用
70         /// </summary>
71         private static void CloseFormInternal()
72         {
73 
74             loadingForm.closeOrder();
75             loadingForm = null;
76 
77         }
78 
79     }                                                                                                                                        

2.LoaderForm窗體具體代碼以下。spa

 1 public partial class LoaderForm : Form
 2 {
 3 
 4         public LoaderForm()
 5         {
 6             InitializeComponent();
 7         }
 8 
 9         /// <summary>
10         /// 關閉命令
11         /// </summary>
12         public void closeOrder()
13         {
14             if (this.InvokeRequired)
15             {  
16                 //這裏利用委託進行窗體的操做,避免跨線程調用時拋異常,後面給出具體定義
17                 CONSTANTDEFINE.SetUISomeInfo UIinfo = new CONSTANTDEFINE.SetUISomeInfo(new Action(() =>
18                 {
19                     while (!this.IsHandleCreated)
20                     {
21                         ;
22                     }
23                     if (this.IsDisposed)
24                         return;
25                     if (!this.IsDisposed)
26                     {
27                         this.Dispose();
28                     }
29 
30                 }));
31                 this.Invoke(UIinfo);
32             }
33             else
34             {
35                 if (this.IsDisposed)
36                     return;
37                 if (!this.IsDisposed)
38                 {
39                     this.Dispose();
40                 }
41             }
42         }
43 
44         private void LoaderForm_FormClosing(object sender, FormClosingEventArgs e)
45         {
46             if (!this.IsDisposed)
47             {
48                 this.Dispose(true);
49             }
50 
51         }
52 
53 }        

對LoaderForm窗體相關說明:線程

1.public delegate void SetUISomeInfo(); //定義一個委託,處理UI相關信息問題。調試

2.LoaderForm窗體上放置了一個label,將其AutoSize屬性設置爲false,並將LoaderForm的TransparencyKey屬性設置爲Transparent(這樣設置避免在加載loading框時出現背景,loading.gif最好選擇透明背景的圖片)。code

至此,一個完整的loading框,已經搞定。orm


by Shawn Chen,2017.7.2日,晚。對象

相關文章
相關標籤/搜索