前言:在項目使用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日,晚。對象