C# 模态进度条

it2022-05-05  84

 很多情况下,我们在处理大数据时需要使用进度条,尤其是以模式窗口打开的进度条。

使用以模式窗口打开的进度条有两个好处。

第一,可以增加用户友好性。

第二,可以防止用户在等待时间多次点击页面按钮。

 

先说一下主要实现思想:

都知道如果在主窗体打开任何一个模式窗口时,当前窗体的进程将停止,知道模式窗口关闭为止,

这时如何才能突破这个一成不变的定律呢?

哈哈猜对了,就是它!使用线程~~~~

我们可以使用一个线程在主窗体上打开一个模式窗口,而且这个模式窗口还不会影响主窗体的线性执行逻辑!

 

下面就是代码实现了:

//1 建立一个有进度条(pbar 为进度条控件的名字)的Form窗体,并外公布几个进度条的必要属性

    #region 属性     /// <summary>     /// 设置进度条的最小值(默认1)     /// </summary>     public int ProgersMinimum     {       set { pbar.Minimum = value; }       get { return pbar.Minimum; }     }     /// <summary>     /// 设置进度条的最最大值(默认100)     /// </summary>     public int ProgersMaximum     {       set { pbar.Maximum = value; }       get { return pbar.Maximum; }     }     /// <summary>     /// 设置进度条的当前值(默认1)     /// </summary>     public int ProgersValue     {       set { pbar.Value = value; }       get { return pbar.Value; }     }     /// <summary>     /// 设置进度条的步长大值(默认1)     /// </summary>     public int ProgersStep     {       set { pbar.Step = value; }       get { return pbar.Step; }     }     #endregion

    #region 方法

    /// <summary>     /// 增加进度     /// </summary>     /// <param name="value">需要增加的值</param>     /// <returns></returns>     public bool Increase(int value)     {       if (!this.IsHandleCreated)         return false;       //关闭进度条窗口       Action WinClose=(()=>{         this.Close();       });

      //设置当前进度条位置       Action<int> SetProgresValue = ((val) => {         if (val < 0 || val > pbar.Maximum || val < pbar.Minimum)         {           pbar.Value = pbar.Maximum;           this.Close();           return;         }

        pbar.Value = val;       });

      try       {         this.Invoke(SetProgresValue, value);       }       catch       {       }

      return !(value < 0 || value > pbar.Maximum || value < pbar.Minimum);     }

    #endregion

//2.接下来就是在主窗体中的逻辑了

//2.1 声明 3 个类的成员变量

    /// <summary>     /// 进度条窗体     /// </summary>     private CommonFrm.FrmProgres m_frmProgres = null;     /// <summary>     /// 控制进度条进度的代理     /// </summary>     /// <returns></returns>     private delegate bool DelIncreaseHandle(int value);     /// <summary>     /// 控制进度条进度的代理变量     /// </summary>     private DelIncreaseHandle m_ctrlProgresIncrease = null;

 

//2.2 编写一个打开进度条窗体的方法,如果要使用进度条时调一下就 OK 了

   /// <summary>     /// 显示进度条     /// </summary>     /// <param name="maxiNum">进度条最大值</param>     /// <param name="miniNum">进度条最小值</param>     private void ShowProgress(int miniNum,int maxiNum)     {       Thread thread = null;       //1 打开进度条窗体       Action showDialogProgress = (() =>       {         m_frmProgres = new CommonFrm.FrmProgres();         m_frmProgres.FormClosed += delegate(object sender, FormClosedEventArgs e)         {

          //添加这行代码会引发异常           //if (null != thread)  //如果进度条界面关闭了,就终止打开窗体的进程           //  thread.Abort();         };         m_ctrlProgresIncrease = new DelIncreaseHandle(m_frmProgres.Increase);         m_frmProgres.ProgersMinimum = miniNum;  //设置进度条的最小值         m_frmProgres.ProgersMaximum = maxiNum;//设置进度条的最大值         m_frmProgres.StartPosition = FormStartPosition.CenterScreen; //进度条窗体打开的位置         m_frmProgres.ShowDialog();  //以模式状态打开进度条窗体

        m_ctrlProgresIncrease = null;         m_frmProgres = null;       });

      //2 启动线程       thread = new Thread(new ThreadStart(showDialogProgress));       thread.IsBackground = false;  // 测试的时候这个东西似乎有点儿影响,没搞明白具体意思呢!       thread.Start();       /*        * 使线程睡眠一会儿,给窗口展现预留时间        * 窗体不展现前 m_ctrlProgresIncrease 为 null        * 将导致使用 this.Invoke 调用 m_ctrlProgresIncrease 委托时页面无限等待        */       Thread.Sleep(1000);     }

// 接下来就是 调用了!!!!!!

    /// <summary>     /// 测试     /// </summary>     private void btnTest_Click(object sender, EventArgs e)     {

      int miniMun = 0;       int maxiNum = 100;       this.ShowProgress(miniMun, maxiNum);  // 打开模式进度条窗口       for (int i = miniMun; i <= maxiNum; i++)       {         if(null != m_ctrlProgresIncrease)           this.BeginInvoke(m_ctrlProgresIncrease, i); // 设置进度条的值

        Thread.Sleep(10);       }       if (null != m_ctrlProgresIncrease)         this.BeginInvoke(m_ctrlProgresIncrease, -1);     }

--------------------------------------

注意:上面用到了 this.BeginInvoke 和 this.Invoke

this.BeginInvoke :不需要等待调用的方法执行完毕

this.Invoke :需要等待调用的方法执行完毕 

--------------------------------------

功能到此结束了!不过还不够灵活,如果在多个页面用还是要将 代码拷贝 过去。

 

 

 

 

转载于:https://www.cnblogs.com/xxj-jing/archive/2012/03/08/2890082.html

相关资源:各显卡算力对照表!

最新回复(0)