Chinaunix首页 | 论坛 | 博客
  • 博客访问: 362362
  • 博文数量: 94
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 823
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-04 16:49
文章分类

全部博文(94)

文章存档

2015年(1)

2011年(1)

2010年(3)

2008年(8)

2007年(55)

2006年(26)

我的朋友

分类:

2008-06-19 16:15:53

程序需求:
主窗体上有一个按钮,点击后显示另外一个窗体 BEPxjForm ,但这个窗体的初始化过程非常缓慢,因此需要在其 new 的过程中显示 进度条 和“正在计算”字样,在 new 完成后隐藏,并且新窗体的 Show() 或 ShowDialog() 方法由主窗体调用。
 
 
解决方法:

//以下部分处于主窗体的类中---------------------------------------------------------

BEPxjForm bepxjF;

private void button1_Click(object sender, EventArgs e)

{

    showCalCtrl();  //显示 正在计算 控件

 

    newBEPxjDT newBEPxjO = new newBEPxjDT(newBEPxjF);

    IAsyncResult res = newBEPxjO.BeginInvoke(null, null);   //注意:是newBEPxjO.BeginInvoke 而不是 this.BeginInvoke

 

    //注意:理论上,这里不需要使用委托而直接调用 ShowProgress() 就可以实现目标,但是实际上如果直接调用,由于主线程会不断的测试辅助线程是否结束和执行 Thread.Sleep() 命令,showCalCtrl() 所执行的使各控件显示的命令虽然执行了,但是界面中却并不能表现出来。因此,必须要使用新的线程来做进度条前进的动作。

    showProDT showProO = new showProDT(ShowProgress);

    showProO.BeginInvoke(res, null, null);  //注意:是 showProO.BeginInvoke 而不是 this.BeginInvoke

}

 

 

//初始化耗时窗体

delegate void newBEPxjDT();

void newBEPxjF()

{

    bepxjF = new BEPxjForm(netCashOut, Tax, discountRate, JF, ZF);  //(耗时过程)

    endBEPxjF();        //在耗时过程完成后,使其他窗体控件等恢复原状

}

 

 

//初始化窗体完成并使其显示,其他窗体控件等恢复原状

delegate void endBEPxjDT();

void endBEPxjF()

{

    if (!this.InvokeRequired)       //如果是主线程自用(本例中不会直接由主线程调用)

    {

        hideCalCtrl();

        bepxjF.ShowDialog();        //由于是由主线程调用的,所以属于主窗体管理

    }

    else                //如果是在辅助线程中调用,由于辅助线程不能直接控制主线程中创建的控件,所以需要使用委托来完成。注意,是使用 this.BeginInvoke 而不是 endBEPxjO.BeginInvoke ,这是与主线程中所用的方法的不同之处

    {

        endBEPxjDT endBEPxjO = new endBEPxjDT(endBEPxjF);

        this.BeginInvoke(endBEPxjO);

    }

}

 

 

//使进度条不断前进

delegate void showProDT(IAsyncResult res);

void ShowProgress(IAsyncResult res)

{

    if (!this.InvokeRequired)   //如果是主线程自用(本例中不会直接由主线程调用)

    {

        while (!res.IsCompleted)

        {

            //这里并不是根据实际执行进度显示进度条的,而是进度条不断向前走,如果达到最大,则变为0,重新前进

            Thread.Sleep(500);

            progressBar1.PerformStep();

            if (progressBar1.Value >= progressBar1.Maximum)

            {

                Thread.Sleep(500);

                progressBar1.Value -= progressBar1.Maximum;

            }

        }

        //如果辅助线程结束了,即耗时的工作已完成,则使进度条快速前进到最大

        while (progressBar1.Value < progressBar1.Maximum)

        {

            progressBar1.PerformStep();

            Thread.Sleep(100);

        }

    }

    else            //如果是在辅助线程中调用,由于辅助线程不能直接控制主线程中创建的控件,所以需要使用委托来完成。注意,是使用 this.BeginInvoke 而不是 showProO.BeginInvoke ,这是与主线程中所用的方法的不同之处

    {

        showProDT showProO = new showProDT(ShowProgress);

        this.BeginInvoke(showProO, new object[] { res });

    }

}

//显示 正在计算 控件

void showCalCtrl()

{

    labelCal.Visible = true;

    progressBar1.Value = progressBar1.Minimum;

    progressBar1.Visible = true;

}

//隐藏 正在计算 控件

void hideCalCtrl()

{

    labelCal.Visible = false;

    progressBar1.Visible = false;

}

//end------------------------------------------------------------------------------

 

阅读(7454) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~