none
Winform如何刷新TextBox缓冲区?(实时显示) RRS feed

  • 问题

  • 如题,比如我有一个按钮的事件处理是:

    private void buttonApply_Click(object sender, EventArgs e)
            {
                try
                {
                    a = textBoxA.Text;
                    Log.Text += "A loaded.\r\n";
                    kz = textBoxKz.Text;
                    Log.Text += "Kz loaded: " + kz + "\r\n";

                    Log.Text += "Start grabbing Voteid...\r\n";
                    GuessVoteid();

                    opt = textBoxOpt1.Text;
                    Log.Text += "Opt loaded: " + opt + "\r\n";

                    this.buttonRun.Enabled = true;

                    Log.Text += "Program initialization completed.\r\n";
                    Log.Text += "Press RUN at any time to start process.\r\n";
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Exception: " + ex.Message, "Error");
                }
            }

    以上,Log是一个textbox;实际运行中GuessVoteid()要占用数秒的时间,这期间导致整个窗体卡死,等这个方法运行完了才会将所有的Text一并显示出。

    求教能否使用一个类似刷新缓冲区的方法,至少在GuessVoteid()执行之前先显示一部分text?目前只发现弹出一个MsgBox可以做到……谢谢!

    2009年9月20日 5:19

答案

全部回复

  • 你好, 使用 Backgroudworker 控件,在 doWork 事件中执行 GuessVoteid(), 在 WorK Complate 事件中对 textBox 赋值
    知识改变命运,奋斗成就人生!
    2009年9月20日 5:30
    版主
  • 你好!
         请问你最后要在Log中显示的文本是否依赖于GuessVoteid()的计算结果?另外,你说“目前只发现弹出一个MsgBox可以做到”,这个我没有理解,MsgBox可以做到什么,在哪里弹出MsgBox呢?
    周雪峰
    2009年9月20日 6:04
    版主
  • 周雪峰MVP, Moderator:
    GuessVoteid本身也会输出到Log一些内容。关于MsgBox,我的意思是如果在GuessVoteid();之前弹出一个msgbox,log里就可以显示出前面的text。
    2009年9月20日 11:14
  • X.X.YModerator:
    感谢回答,成功了。

    另外再问一句,能否使用什么命令等待这个Backgroudworker执行之后再继续后面的代码?因为现在的情况是所有消息都显示完了以后过了几秒钟才显示GuessVoteid()的结果的
    • 已编辑 FrankLSF95 2009年9月20日 11:30 disambig
    2009年9月20日 11:17
  • 你好!你可以在第一个 BackgroundWorker 的 WorkComplate 事件中去 Run 第二个 BackgroupWorker, 以上类推
    知识改变命运,奋斗成就人生!
    2009年9月21日 1:12
    版主
  • 你如果等待Backgroudworker结束的话,就失去这样做的意义了,这和你一开始的方法一样了啊!
    周雪峰
    2009年9月21日 5:03
    版主
  • 这样不会呀,一个线程结束后通过加回调使得下一个线程开始,这和楼主一开始的写法是不一样的。
    知识改变命运,奋斗成就人生!
    2009年9月21日 5:17
    版主
  • 另外你可以在线程中使用 BeginInvoke 来设置控件的属性,如:
    -----------------------------------------------------------------
    public delegate void ClientDelegate();
    
    private void button1_Click(object sender, EventArgs ex)
    {
        using (BackgroundWorker backgroundWorker = new BackgroundWorker())
        {
            backgroundWorker.DoWork += new DoWorkEventHandler(delegate(object o, DoWorkEventArgs workerEventArgs)
            {
                for (int i = 0; i < 1000; i++)
                {
                    this.AppendText(
                        delegate
                        {
                            this.richTextBox1.Text += "X";
                        });
                    Thread.Sleep(100);
                }
            });
    
            backgroundWorker.RunWorkerAsync();
        }
    }
    
    private void AppendText(ClientDelegate d)
    {
        this.BeginInvoke(d);
    }


    知识改变命运,奋斗成就人生!
    2009年9月21日 5:20
    版主
  • 这样不会呀,一个线程结束后通过加回调使得下一个线程开始,这和楼主一开始的写法是不一样的。
    知识改变命运,奋斗成就人生!
    是的啊!多谢指教!

    周雪峰
    2009年9月21日 5:57
    版主
  • 不客气~!相互学习!
    知识改变命运,奋斗成就人生!
    2009年9月21日 6:03
    版主
  • 你好!你可以在第一个 BackgroundWorker 的 WorkComplate 事件中去 Run 第二个 BackgroupWorker, 以上类推
    知识改变命运,奋斗成就人生!
    感谢诸位的回答,等我有空或周末再细细研究~
    您的意思是把每一组操作都包在一个BackgroundWorker里执行以避免winform无响应?
    另,小提醒:是“Complete” :)
    2009年9月21日 13:22
  • 你好,是的,是这样的. BackgroundWorker 就是干这样的工作的。
    知识改变命运,奋斗成就人生!
    2009年9月22日 4:44
    版主
  • 您好,我想再问一下关于Progressbar的问题。我新建了一个事件:

    private void bgwGuess_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                this.progressBar1.Value = e.ProgressPercentage;
            }

    然后在这个bgworker的执行方法(GuessVoteid())中加入了几行

    bgwGuess.ReportProgress(50); 之类的语句,结果执行的时候却发现GuessVoteid()这个方法整个就没有运行了……请指教。
    2009年9月23日 10:30
  • 请问可以说说你是怎么做的吗?最好提供相关代码!
    周雪峰
    2009年9月23日 10:47
    版主
  • 请问可以说说你是怎么做的吗?最好提供相关代码!
    周雪峰
    我也不太记得了……反正现在弄好了:)
    2009年9月23日 11:15