WinForm下的loading框的實現


前言:在項目使用C/S模式情況下,由於需要經常進行數據的刷新,如果直接進行刷新,會有一個等待控件重畫的過程,非常的不友好,因此在這里添加一個loading框進行等待顯示。

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


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

 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窗體具體代碼如下。

 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最好選擇透明背景的圖片)。

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


by Shawn Chen,2017.7.2日,晚。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM