当前位置:主页   - 电脑 - 程序设计 - C#
c#中如何控制模态子窗体中的进度条
来源:网络   作者:   更新时间:2012-02-05
收藏此页】    【字号    】    【打印】    【关闭

  这个问题会让一些初学者感到困惑,一方面模态窗体在打开之后(Form.ShowDialog).主线程无法继续执行下面的事务;另一方面,又要在处理事务的时候来同步这个窗体里面的进度条。这两件事情都必须做,却都不能先做...

  所以很多人不得不把事务处理写到模态窗体当中去,这样可以达到目的,却造成了代码结构混乱,而且子窗体无法复用,如果有多个事物,不得不为每个事务来写控制窗体。

  这里我们介绍一种比较直接了当的方法,就是主线程中开启两个子线程,一个用于显示模态窗体,一个用于处理事务, 并同时更新第一个线程中的窗体信息。

  这里的知识范畴会包含线程的基础用法,线程和UI之间的交互,以及委托的基本用法。如果你还不了解这几点,可以参考一些其他资料,比如我先前写过的,在同一窗体中用子线程来控制进度条

  http://blog.csdn.net/jinjazz/archive/2008/05/06/2397136.aspx

  这里的应用稍微复杂一些,你可以先用Vs2005新建一个Windows Application,这个application包含两个窗体,一个Form1,为主窗体,一个Form2,为模态子窗体。Form1,中添加Button1,用来开启测试。Form2中添加进度条ProgressBar1和一个用来取消事务的按钮Button1。然后把如下代码贴入测试程序中的两个form里面。

  Form1,主窗体

using System;
using System.Windows.Forms;
  
namespace WindowsApplication39
...{
  public partial class Form1 : Form
  ...{
  
    delegate void dShowForm();
    Form2 frm = new Form2();
  
    public Form1()
    ...{
      this.InitializeComponent();
    }
    //显示窗体
    void ShowForm()
    ...{
      if (this.InvokeRequired)
      ...{
        this.Invoke(new dShowForm(this.ShowForm));
      }
      else
      ...{
        frm.ShowDialog(this);
      }
    }
    //控制进度
    void SetProgress()
    ...{
      for (int i = 1; i <= 100; i++)
      ...{
        if (frm.DialogResult == DialogResult.Cancel)
        ...{
          //判断取消
          break;
        }
        else
        ...{
          //模拟进度
          frm.SetProgress(100, i);
          System.Threading.Thread.Sleep(50);
        }
      }
    }
    private void button1_Click(object sender, EventArgs e)
    ...{
      new System.Threading.Thread(new System.Threading.ThreadStart(ShowForm)).Start();
      new System.Threading.Thread(new System.Threading.ThreadStart(SetProgress)).Start();
    }
  }
}
Form2,模态窗体

using System;
using System.Windows.Forms;
namespace WindowsApplication39
...{
  public partial class Form2 : Form
  ...{
    public Form2()
    ...{
      InitializeComponent();
    }
  
    public delegate void dSetProgress(int total, int current);
  
    public void SetProgress(int total, int current)
    ...{
      if (this.InvokeRequired)
      ...{
        try
        ...{
          this.Invoke(new dSetProgress(this.SetProgress), new object[] ...{ total, current });
        }
        catch ...{ }
      }
      else
      ...{
        this.progressBar1.Maximum = total;
        this.progressBar1.Value = current;
      }
    }
  
    private void button1_Click(object sender, EventArgs e)
    ...{
      this.DialogResult = DialogResult.Cancel;
    }
  }
}

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明