• 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
        }
    }
  • 相关阅读:
    Max History CodeForces
    Buy a Ticket CodeForces
    AC日记——字符串的展开 openjudge 1.7 35
    AC日记——回文子串 openjudge 1.7 34
    AC日记——判断字符串是否为回文 openjudge 1.7 33
    AC日记——行程长度编码 openjudge 1.7 32
    AC日记——字符串P型编码 openjudge 1.7 31
    AC日记——字符环 openjudge 1.7 30
    AC日记——ISBN号码 openjudge 1.7 29
    AC日记——单词倒排 1.7 28
  • 原文地址:https://www.cnblogs.com/yedaoq/p/1704678.html
Copyright © 2020-2023  润新知