zoukankan      html  css  js  c++  java
  • 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日,晚。

  • 相关阅读:
    element 三级复选框
    element 复选框问题
    vue 的样式穿透(深度选择器) >>>
    随笔,用于直接复制粘贴
    element 弹窗无法重新赋值的问题
    @vue/cli 4.2.3版本的本地json读取和跨域配置(与旧版本vue不同)
    element表格及接口的对接
    axios的post请求即自动刷新
    Puppeteer 安装及失败原因
    Redis的安装
  • 原文地址:https://www.cnblogs.com/developer_chan/p/7107599.html
Copyright © 2011-2022 走看看