您的位置:首页 > 运维架构

BusyTipOperator——显示提示窗体的实现(二)

2010-04-05 15:08 211 查看
前 注:

这是自己平时根据自己需要写的一些小代码,未必对各看官有用。另外,这是根据个人想法而写,未必严谨和符合设计原则,若有任何不妥之处,还请不吝赐教。

说 明:

本文描述一个根据 《BusyTip——显示提示窗体的实现(一) 》中所述思路设计的一个用于显示提示窗体的功能接口的实现。本实现在一个守候线程上循环弹出模态对话框,并封装了触发弹出、关闭对话框事件的接口。

要 点:

1.  TipThread为守候线程,线程方法为TipThreadRun。此方法在循环中等待ShowTipEvent事件,当该事件发生时弹出对话框,并进入阻塞状态;直到对话框关闭,然后线程开始等待下一次ShowTipEvent事件。
2.  Start方法通过触发ShowTipEvent事件来通知TipThread显示对话框,Stop方法通过调用对话框的Close方法来关闭对话框。
3.  Start、Stop与Monitor的Enter、Exit有些相似的特性:Start可以重复进入(效果不变),但调用多少次Start,就必须调用多少次Stop,才能合提示窗体关闭。
4.  可以使用SetProperty方法来设置提示窗体的属性,此方法使用反射与Invoke来实现其功能。BusyTipOperator.Text成员的set访问器是SetProperty("Text",value)的快捷形式。同样的,也可以为进度等其它数据添加类似属性。
5.  当State属性值为Released时,表示此BusyTipOperator对象已经释放其资源,不应再被使用。

.jpg]



 

示例:

for (int i = 0; i < 5; ++i)
{
busytip.Start();
busytip.Start(string.Format("循环:{0}...",i));

Thread.Sleep(1000);
busytip.Stop();
//Thread.Sleep(100);
busytip.Stop();
}


源 码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;

namespace CommonLibrary.BusyTip
{
/// <summary>
/// 调用委托
/// </summary>
public delegate void DelegateInvoke();

/// <summary>
/// 不考虑线程安全的设置属性委托
/// </summary>
/// <param name="Value">属性值</param>
public delegate void DelegateSetProperty(string PropertyName, object Value);

/// <summary>
/// 提示对象状态的枚举
/// </summary>
public enum EnumBusyTipOperatorState
{
/// <summary>
/// 正在显示提示窗体
/// </summary>
Show,

/// <summary>
/// 空闲,未显示提示窗体
/// </summary>
Free,

/// <summary>
/// 已释放,无法再显示提示窗体
/// </summary>
Released
};

/// <summary>
/// 使用提示窗体的接口
/// </summary>
public class BusyTipOperator:IDisposable
{
#region Constructor & Destructor

/// <summary>
/// 构造函数
/// </summary>
public BusyTipOperator(Form tipDialog)
{
FrmTip = tipDialog;
FrmTip.ShowInTaskbar = false;
FrmTip.Load += new EventHandler(FrmTip_FormLoad);

ShowTipEvent = new AutoResetEvent(false);
FrmOpCompletedEvent = new AutoResetEvent(false);

DelegateSetProperty = new DelegateSetProperty(this.SetProperty);

TipThread = new Thread(new ThreadStart(this.TipThreadRun));
TipThread.Start();
}

/// <summary>
/// 析构函数
/// </summary>
~BusyTipOperator()
{
if (!Disposed) Dispose();
}

#endregion

#region Fields

///// <summary>
///// 显示的图片
///// </summary>
//public String _PictureAddress;

///// <summary>
///// 是否允许取消
///// </summary>
//public bool _CancelEnabled = true;

///// <summary>
///// 父窗体是否可用
///// </summary>
//public bool _ParentEnabled = false;

///// <summary>
///// 标记是否终止守护线程
///// </summary>
//public bool StopTipThread = false;

/// <summary>
/// 提示窗体
/// </summary>
private Form FrmTip;

/// <summary>
/// 用于显示提示窗体的线程
/// </summary>
private Thread TipThread;

/// <summary>
/// 触发显示提示窗体操作的事件
/// </summary>
private AutoResetEvent ShowTipEvent;

/// <summary>
/// 此事件在窗体操作完成时发出通知
/// </summary>
private AutoResetEvent FrmOpCompletedEvent;

private DelegateSetProperty DelegateSetProperty;

/// <summary>
/// 当前提示的状态
/// </summary>
private EnumBusyTipOperatorState _State = EnumBusyTipOperatorState.Free;

/// <summary>
/// 是否终止显示线程
/// </summary>
private bool StopTipThread = false;

/// <summary>
/// 非托管资源释放标志
/// </summary>
private bool Disposed = false;

/// <summary>
/// 锁,用于同步窗体的打开/关闭过程
/// </summary>
private object Lock = new object();

/// <summary>
/// 统计调用Start的嵌套层数(即当前需要调用Stop的次数)
/// </summary>
private int ShowCount = 0;

#endregion

#region Properties

/// <summary>
/// 当前提示窗体的状态
/// </summary>
public EnumBusyTipOperatorState State
{
get { return _State; }
}

/// <summary>
/// 提示内容
/// </summary>
public string Text
{
get
{
return FrmTip.Text;
}
set
{
SetProperty("Text", value);
}
}

/// <summary>
/// 是否允许取消,此设置项暂时无效,默认为否
/// </summary>
public bool CancelEnabled
{
get { return false; }
set
{

}
}

/// <summary>
/// 父窗体是否可用,此设置项暂时无效,默认为否
/// </summary>
public bool ParentEnabled
{
get { return false ; }
set
{

}
}

#endregion

#region Operator Interface

/// <summary>
/// 开始显示提示窗体
/// </summary>
public int Start()
{
Monitor.Enter(Lock);

++ShowCount;

if (this.State == EnumBusyTipOperatorState.Free)
{
_State = EnumBusyTipOperatorState.Show;

//通过ShowTipEvent事件向TipThread发送信息,使其显示提示窗体
ShowTipEvent.Set();

//等待提示窗体显示完成的信号  &  也可以通过以下方式实现:使当前线程挂起,然后在FrmTip_Load中恢复
FrmOpCompletedEvent.WaitOne();
}

Monitor.Exit(Lock);

return 1;
}

/// <summary>
/// 开始显示提示窗体并在其中显示指定的提示文本
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public int Start(string Text)
{
this.Text = Text;
return Start();
}

/// <summary>
/// 终止显示提示窗体
/// </summary>
public int Stop()
{
Monitor.Enter(Lock);

do
{
if (ShowCount <= 0) break;
if (--ShowCount > 0) break;

_State = EnumBusyTipOperatorState.Free;

FrmTip.Invoke(new DelegateInvoke(FrmTip.Close));

FrmOpCompletedEvent.WaitOne();

} while (false);

Monitor.Exit(Lock);

return 1;
}

/// <summary>
/// 设置提示窗体的提示文本
/// </summary>
/// <param name="Text"></param>
public void SetProperty(string PropertyName,object Value)
{
if (FrmTip.InvokeRequired)
{
FrmTip.Invoke(DelegateSetProperty, PropertyName, Value);
}
else
{
FrmTip.GetType().InvokeMember(PropertyName, System.Reflection.BindingFlags.SetProperty, null, FrmTip, new object[] { Value });
}
}

#endregion

#region Innerl Methods

/// <summary>
/// 用来显示提示框的守护线程
/// </summary>
private void TipThreadRun()
{
ShowTipEvent.WaitOne();
while (!StopTipThread)
{
FrmTip.ShowDialog();
FrmOpCompletedEvent.Set();
ShowTipEvent.WaitOne();
}
}

/// <summary>
/// 释放非托管资源
/// </summary>
public void Dispose()
{
Disposed = true;

if (this.State == EnumBusyTipOperatorState.Show) Stop();
StopTipThread = true;
ShowTipEvent.Set();
TipThread.Join();
_State = EnumBusyTipOperatorState.Released;
}

/// <summary>
/// 提示窗体加载完成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void FrmTip_FormLoad(object sender, EventArgs e)
{
FrmOpCompletedEvent.Set();
}

#endregion
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐