惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
H
Heimdal Security Blog
K
Kaspersky official blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Schneier on Security
G
GRAHAM CLULEY
U
Unit 42
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
C
Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
Security Archives - TechRepublic
Security Archives - TechRepublic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
Jina AI
Jina AI
P
Proofpoint News Feed
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Application and Cybersecurity Blog
Application and Cybersecurity Blog
IT之家
IT之家
S
Security Affairs
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
N
News | PayPal Newsroom
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
NISL@THU
NISL@THU

博客园 - Pvistely

SQL查询日历 怀旧下给自己留个备份, FluorineFx ASObject自动转换基础类 AutoParseASObject ,用于Flash AMF协议解析 PPPOE数据包转换及SharpPcap应用 Flash网页游戏辅助工具制作简析 Microsoft SQL Server 2008 基本安装说明 SQL 2000 异数据库数据同步 请把这个消息提示框拿掉,谢谢 MS新版Wallop, 被VB6搞死。。。。。。。鸟 企业管理应用系统平台插件接口应用说明 企业管理应用系统平台应用说明 企业管理应用平台预览演示版下载 企业管理系统应用平台(预览版) ENA13条码转换函数 运行时自定义PropertyGrid显示属性项目 C1Flexgrid与XtraGrid性能比较 继上次的GDI+做报表设计器后............. 想用GDI+2.0做设计器,但在实现过程中遇到大麻烦
小东西WinForm的等待窗口
Pvistely · 2009-11-27 · via 博客园 - Pvistely

一般在做WinForm应用时会遇到较长时间的用户操作等待,此时最好加个等待窗口,给用户一个良好的操作体验.

太懒本来想在网上找一个代码的,但没找到合适的,只能自己动手写一个了,附上代码,也给自己做个备份

包括一个private的内建等待窗口类,及一个public的WaitForm类

WaitForm类提供Show及Close两个方法,代码中等待窗口不为模式窗口

在应用中需要操作长时间运作时可用下面的模式调用:

WaitForm.Show(this);//显示等待窗口

DoSomthing();//主窗口长时间操作

WaitForm.Close();//关闭等待窗口

这段代码主要应用了多线程方式完成,使用一个AutoResetEvent事件信号量来做窗口状态处理,并增保证了等待窗口在异常关闭的情况下能正确的退出显示线程.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace BMSAP.Windows
{
  


    
public delegate void ExecutedInvokeHeandle();/// <summary>
    
/// 等待窗口
    
/// </summary>
    public class WaitForm
    {
        
/// <summary>
        
/// 等待窗口对象
        
/// </summary>
        static FrmWait mWait;
        
/// <summary>
        
/// 事件状态通知
        
/// </summary>
        static AutoResetEvent mEvents;
        
/// <summary>
        
/// 显示状态
        
/// </summary>
        static bool mShowing = false;
        
/// <summary>
        
/// 等待状态
        
/// </summary>
        static bool mWaiting = false;
        
static WaitForm()
        {
            
//全局等待信号
            mEvents = new AutoResetEvent(false);
        }
        
/// <summary>
        
/// 窗口关闭事件
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        static void WaitForm_FormClosed(object sender, FormClosedEventArgs e)
        {
if (mWaiting || !(sender is FrmWait))
            {
                
//信号等待中被异常关闭,或主窗口被关闭时自动通知信号复位
                mEvents.Set();
                
return;
            }
            mShowing 
= false;
            
//回收等待窗口
            try
            {
                mWait.Dispose();
            }
            
finally
            {
                mWait 
= null;
            }
        }
        
/// <summary>
        
/// 显示等待窗口
        
/// </summary>
        
/// <param name="pComponet">调用对象,可为控件或窗口</param>
        public static void Show(Control pComponet)
        {
            
//已显示则返回
            if (mShowing)
                
return;
            
//创建等待窗口
            mWait = new FrmWait();
            
//设置窗口关闭事件
            mWait.FormClosed += new FormClosedEventHandler(WaitForm_FormClosed);
            
//启动显示线程
            Thread tmpThread = new Thread(show);
            tmpThread.Start(pComponet);
        }
        
/// <summary>
        
/// 关闭等待窗口
        
/// </summary>
        public static void Close()
        {
if (mShowing)
                
//如果显示中则设置关闭信号
                mEvents.Set();
            
//修改等待状态
            mWaiting = false;
        }
        
/// <summary>
        
/// 显示窗口过程
        
/// </summary>
        
/// <param name="pComponet"></param>
        static void show(object pComponet)
        {
            
if (pComponet != null &&
                pComponet 
is Control)
            {
                
//设置显示状态
                mShowing = true;
                
//当调用对象为Win控件时
                (pComponet as Control).BeginInvoke(new ExecutedInvokeHeandle(delegate()
                {
                    
//进行异步调用
                    if (pComponet != null &&
                        pComponet 
is Control)
                    {
                        
//显示等待窗口
                        mWait.Show((pComponet as Control).FindForm());
                        
//设置父级窗口关闭事件
                        (pComponet as Control).FindForm().FormClosed += new FormClosedEventHandler(WaitForm_FormClosed);
                        
//激活父级窗口,
                        (pComponet as Control).FindForm().Activate();
                    }
                    
else
                    {
                        
//如查询不到父级窗口设置顶层显示,此处可用GetDesktop的API来获取桌面窗口,并设置为父级窗口
                        mWait.TopMost = true;
                        
//显示等待窗口
                        mWait.Show();
                    }
                }));
                
//设置等待信号
                mWaiting = true;
                mEvents.WaitOne();
                
//等待结束
                mWaiting = false;
                (pComponet 
as Control).BeginInvoke(new ExecutedInvokeHeandle(delegate()
                {
                    
//关闭窗口
                    mWait.Close();
                }));

            }
        }
    }
}