前言:在项目使用C/S模式情况下,由于需要经常进行数据的刷新,如果直接进行刷新,会有一个等待控件重画的过程,非常的不友好,因此在这里添加一个loading框进行等待显示。

实现:在经过多方面查询资料,终于是实现了一个完整的loading框程序,这里主要解决在多次点击查询按钮或者加载数据时出现的:执行 CreateHandle() 时无法调用值 Close()或者无法访问已释放的对象或者在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。这三个问题困扰我很久,最终通过不断的调试,将其解决,话不多说,直接上代码。


1.下面类为loading框帮助类,在实际调用过程中,使用该类调用相关函数即可。

 class LoadingHelper
{
#region 相关变量定义
/// <summary>
/// 定义委托进行窗口关闭
/// </summary>
private delegate void CloseDelegate();
private static LoaderForm loadingForm;
private static readonly Object syncLock = new Object(); //加锁使用 #endregion private LoadingHelper()
{ } /// <summary>
/// 显示loading框
/// </summary>
public static void ShowLoadingScreen()
{
// Make sure it is only launched once.
if (loadingForm != null)
return;
Thread thread = new Thread(new ThreadStart(LoadingHelper.ShowForm));
thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.STA);
thread.Start(); } /// <summary>
/// 显示窗口
/// </summary>
private static void ShowForm()
{
if (loadingForm != null)
{
loadingForm.closeOrder();
loadingForm = null;
}
loadingForm = new LoaderForm();
loadingForm.TopMost = true;
loadingForm.ShowDialog();
} /// <summary>
/// 关闭窗口
/// </summary>
public static void CloseForm()
{
Thread.Sleep(); //可能到这里线程还未起来,所以进行延时,可以确保线程起来,彻底关闭窗口
if (loadingForm != null)
{
lock (syncLock)
{
Thread.Sleep();
if (loadingForm != null)
{
Thread.Sleep(); //通过三次延时,确保可以彻底关闭窗口
loadingForm.Invoke(new CloseDelegate(LoadingHelper.CloseFormInternal));
}
}
}
} /// <summary>
/// 关闭窗口,委托中使用
/// </summary>
private static void CloseFormInternal()
{ loadingForm.closeOrder();
loadingForm = null; } }

2.LoaderForm窗体具体代码如下。

 public partial class LoaderForm : Form
{ public LoaderForm()
{
InitializeComponent();
} /// <summary>
/// 关闭命令
/// </summary>
public void closeOrder()
{
if (this.InvokeRequired)
{
//这里利用委托进行窗体的操作,避免跨线程调用时抛异常,后面给出具体定义
CONSTANTDEFINE.SetUISomeInfo UIinfo = new CONSTANTDEFINE.SetUISomeInfo(new Action(() =>
{
while (!this.IsHandleCreated)
{
;
}
if (this.IsDisposed)
return;
if (!this.IsDisposed)
{
this.Dispose();
} }));
this.Invoke(UIinfo);
}
else
{
if (this.IsDisposed)
return;
if (!this.IsDisposed)
{
this.Dispose();
}
}
} private void LoaderForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (!this.IsDisposed)
{
this.Dispose(true);
} } }

对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日,晚。

最新文章

  1. C#发送邮箱
  2. mybatis Generator生成代码及使用方式
  3. Touch ID使用
  4. php抓取网页信息
  5. fail2ban 原理 安装 使用
  6. SQL数据库对于保存特殊字符的解决办法
  7. Direct2D开发:从资源加载位图
  8. /dev/ttySn(转)
  9. cssText在 IE6/7/8和chrome/Firefox/IE9+的不同
  10. iOS - UI - UIWebView
  11. javascript学习笔记20160121-css选择器
  12. Linux无处不在
  13. winform窗体中查找控件
  14. hdu 4686 Arc of Dream(矩阵快速幂乘法)
  15. perl 匿名函数传参
  16. Android设备管理器漏洞2--禁止用户取消激活设备管理器
  17. WebView混合开发
  18. [Noi2016]网格
  19. 摄像头ov2685中关于sensor id 设置的相关的寄存器地址
  20. InstallShield 创建 visual studio 工程的时候 指向 任意 visual studio 版本 方法 (修改 计算机 默认 visual studio shell 版本)

热门文章

  1. Hangfire定时任务设置CronExpression表达式
  2. c# 使用迭代器来创建可枚举类型
  3. 动态编程(Dynamic Programming)
  4. 推荐数据库、Web、Net、架构的PDF数据,书不在多,在看!
  5. [android] android消息机制入门
  6. 挑战常规--搭建gradle、maven私人仓库很简单
  7. Flask 系列之 Bootstrap-Flask
  8. xml方式封装数据方法
  9. html5对于seo有哪些优势
  10. 学用纯CSS打造可折叠树状菜单