C# 模态进度条

来源:互联网 发布:网络解决方案ppt 编辑:程序博客网 时间:2024/06/01 09:30

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

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

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

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

 

先说一下主要实现思想:

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

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

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

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

 

下面就是代码实现了:

//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 :需要等待调用的方法执行完毕 

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

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

 

 

 

 

原创粉丝点击