zoukankan      html  css  js  c++  java
  • BusyTipOperator——显示提示窗体的实现(二)

    前 注:

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

    说 明:

    本文描述一个根据 《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对象已经释放其资源,不应再被使用。

    未命名

    示例:

    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
        }
    }
  • 相关阅读:
    js_css_dl.dt实现列表展开、折叠效果
    property_自己编写一个读取Property文件的Util类
    HttpClient_002_中文乱码、HttpClient中文乱码透析、总结
    HttpClient_001_初步实现项目01的servlet,与项目02的servlet,之间数据访问
    jsp:中文乱码解决
    linux命令
    js 监测from表单中的input和select,时时监测,没有输入或选择信息报错,不允许提交数据
    数据库的那些事
    待参考
    layer.open多次触发,遮罩层覆盖content的解决办法
  • 原文地址:https://www.cnblogs.com/yedaoq/p/1704678.html
Copyright © 2011-2022 走看看