我想实现这样的一个效果,请哪位高手指点一下
 
 程序中会执行一个很耗时的存储过程,我想在用户点击按钮后,弹出一个进度条窗口,显示正在执行的进度,执行完成后,进度条窗口关闭,回到主程序窗口。
 同时,希望在执行的时候用户也可以在主程序窗口进行其它操作,不会一点击全变白了,跟没有响应一个状态。
请高手指点下啊?
最好是能有比较简洁的代码,谢谢

解决方案 »

  1.   

    Form1:
    -------------------------------------------------------------------------------------------
    控件:Button1
    ------------------------------------------------------------------------------------------
    private void button1_Click(object sender, System.EventArgs e)
      {
       Form2 pj=new Form2();
       pj.Show();
       //开始处理大量耗时工作
       string sor="";
       int j = 10000;
       for(int i=0;i<j;i++)
       {
        sor+=i.ToString();
        if(i%(j/100)==0)
        {
         pj.progressBar1.Value++;
         pj.label1.Text="已完成:"+string.Format("{0:p}",(double)pj.progressBar1.Value/100);
         Application.DoEvents();
        }
       }
       //工作完成,关闭进度条窗体
       pj.Close();
      }
    -------------------------------------------------------------------------------------
     
    Form2:
    -------------------------------------------------------
    控件:Label1、progressBar1
    ------------------------------------------------------
      

  2.   

    能不能说具体点呢?
    还有我一运行线程就会有这样的错误提示
    线程间操作无效: 从不是创建控件“pbr”的线程访问它。
    请问这个是什么错误呢?
      

  3.   

    哪个帮我看看这段代码到底错在哪里呢?为什么我一运行就报
    线程间操作无效: 从不是创建控件“pbr”的线程访问它。 using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Threading ;namespace DIKABudgetSystem
    {
    /// <summary>
    /// 进度条显示 的摘要说明。
    /// </summary>
    public class frmProgressShow : System.Windows.Forms.Form
    {
    private System.ComponentModel.IContainer components;
    // Create a MainMenu object and a MenuItem object.
    int lngTime1;
    int lngTime2;
            int lngTime3;
            private ProgressBar pbr;
            private System.Windows.Forms.Timer timer1;
            private StatusBar s;
    private System.Windows.Forms.StatusBarPanel s1;
    private System.Windows.Forms.StatusBarPanel s2;
    private System.Windows.Forms.PictureBox pictureBox1;
    private System.Windows.Forms.StatusBarPanel s3;
    public frmProgressShow()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent();
    // AppStartMenu();
    //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if(components != null)
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    }
    private void frmProgressShow_Load(object sender, System.EventArgs e)
    {
                //this.Show();
                //TakeTime();
                //PbrShow();
              //  TakeTime1();
                Thread t2 = new Thread(new ThreadStart(Show));
                t2.Start();
                Thread t = new Thread(new ThreadStart(TakeTime));
                t.Start();
                Thread t1 = new Thread(new ThreadStart(PbrShow));
                t1.Start();
                Thread t3 = new Thread(new ThreadStart(TakeTime1));
                t3.Start();
    }
    public void TakeTime()
    {
    try
    {
    for(int i=0;i<3200;i++) {
    s.Panels[0].Text =i.ToString();
    }
    this.Close();
    }
    catch
    {
    this.Close(); }
    }
    public void TakeTime1()
    {
    TimerCallback callback = new TimerCallback (TimeShow); 
    System.Threading.Timer timer = new System.Threading.Timer(callback, null, 1000, 1000);  }
    public void PbrShow()
    {
    pbr.Maximum =2000;
    pbr.Minimum =0; for(int i=0;i<2000;i++) {
    pbr.Value  =i;
    }
    this.Close();
    }
    public void TimeShow(object state)
    {
    s.Panels[1].Text = "正在加载数据,请您稍后 ...";
    lngTime1 = lngTime1 + 1;
    if (lngTime1 == 60)
    {
    lngTime2 = lngTime2 + 1;
    lngTime1 = 0;
    }
    if (lngTime2 == 60)
    {
    lngTime3 = lngTime3 + 1;
    lngTime2 = 0;
    }
    string h;
    string t;
    string c;
    if (lngTime3.ToString().Length==2 )
    {
    h=lngTime3.ToString() ;
    }
    else
    {
    h="0" +lngTime3.ToString() ;
    }
    if (lngTime2.ToString().Length==2 )
    {
    t=lngTime2.ToString() ;
    }
    else
    {
    t="0" +lngTime2.ToString() ;
    }
    if (lngTime1.ToString().Length==2 )
    {
    c=lngTime1.ToString() ;
    }
    else
    {
    c="0" +lngTime1.ToString() ;
    }
    s.Panels[1].Text  = "Time [" + h+ ":" + t + ":" +c;
    }

    private void timer1_Tick(object sender, System.EventArgs e)
    {
    // string strMsg;
    ////''If Timer1.Enabled = False Then Exit Sub
    s.Panels[1].Text = "正在加载数据,请您稍后 ...";
    lngTime1 = lngTime1 + 1;
    if (lngTime1 == 60)
    {
    lngTime2 = lngTime2 + 1;
    lngTime1 = 0;
    }
    if (lngTime2 == 60)
    {
    lngTime3 = lngTime3 + 1;
    lngTime2 = 0;
    }         string h;
    string t;
    string c;
    if (lngTime3.ToString().Length==2 )
    {
    h=lngTime3.ToString() ;
    }
    else
    {
    h="0" +lngTime3.ToString() ;
    }
    if (lngTime2.ToString().Length==2 )
    {
    t=lngTime2.ToString() ;
    }
    else
    {
    t="0" +lngTime2.ToString() ;
    }
    if (lngTime1.ToString().Length==2 )
    {
    c=lngTime1.ToString() ;
    }
    else
    {
    c="0" +lngTime1.ToString() ;
    }
    s.Panels[1].Text  = "时间[" + h+ ":" + t + ":" +c+"]";
    } }
    }
      

  4.   

    此句是关键Application.DoEvents(); 
      

  5.   

    不能在你建的线程中操作UI控件。可以在线程中用Invoke控件。
    如:
       定义一个方法
           //更新 界面
            private void updatelistbox(object str)
            {
                listBox1.Items.Add((string)str);
            }  然后可以在线程中这样调用:       listBox1.Invoke(new ParameterizedThreadStart(updatelistbox), "str参数");  
      

  6.   

    写错了
    可以在线程中用Invoke调用。