• 实时刷新Winform中Label的Text


    最直白的例子:

     private void btnStart_Click(object sender, EventArgs e)
            {           
                int i = 0;
                while (i < 60)
                {
                    labelTime.Text = i.ToString();
                    Thread.Sleep(1000);
                }
            }

    运行的时候窗口死在哪里似的,不能动。这是不对的,下面看两种对的方法:

    第一种方法:Timer

    System.Windows.Forms.Timer 用于以用户定义的事件间隔触发事件。 Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。 它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。

    使用此计时器时,请使用 Tick 事件执行轮询操作,或在指定的时间内显示启动画面。 每当 Enabled 属性设置为 true 且 Interval 属性大于 0 时,将引发 Tick 事件,引发的时间间隔基于 Interval 属性设置。

    此类提供用于设置时间间隔以及启动和停止计时器的方法。

    Windows 窗体 Timer 组件是单线程组件,精度限定为 55 毫秒。 如果您需要更高精度的多线程计时器,请使用 System.Timers 命名空间中的 Timer 类。

    private void btnStart_Click(object sender, EventArgs e)
            {
                System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                timer.Interval = 1000;
                timer.Tick += new EventHandler(RefreshTime);
                timer.Enabled = true;
                timer.Start();
            }
           
            private void RefreshTime(object sender, EventArgs e)
            {
                int n = int.Parse(labelTime.Text);
                if (n > 0)
                {
                    labelTime.Text = (n - 1).ToString();
                }
                else
                {
                    ((System.Windows.Forms.Timer)sender).Stop();
                }
            }

    窗口开可以动,还会有反应。

    第二种方法:Thread

    有时候我们需要创建一个线程,在线程里做这件事情。刷新Label必须由窗体主线程来做,具体做法是在创建的线程里把一个委托交给主线程。

     Thread threadScan;//线程
            long num = 0L;//计数
    
            private void btnScan_Click(object sender, EventArgs e)
            {
                num = 0L;
                threadScan = new Thread(new ThreadStart(ScanFile));
                threadScan.Start();
            }
    //线程触发的方法
     private void ScanFile()
            {
                SetText st = new SetText(UpdateLabel);
                while (num < 10)
                {
                    if (labelScan.InvokeRequired)
                    {
                        labelScan.Invoke(st, num.ToString());//交给主线程
                    }
                    else
                    {
                        labelScan.Text = num.ToString();
                    }
                    num++;
                    Thread.Sleep(1000);
                }
                threadScan.Abort();
            }
    //委托
            public delegate void SetText(string text);
    //委托调用的方法
            private void UpdateLabel(string str)
            {
                labelScan.Text = str;
            }

    顺便写一个匿名委托的例子

     private void ScanFile()
            {
                while (num < 10)
                {
                    if (labelScan.InvokeRequired)
                    {
                        SetText st = delegate(string str)
                            {
                                labelScan.Text = str;
                            };
                        labelScan.Invoke(st, num.ToString());
                    }
                    else
                    {
                        labelScan.Text = num.ToString();
                    }
                    num++;
                    Thread.Sleep(1000);
                }
                threadScan.Abort();
            }

    不用方法,不用new,对象等于delegate(参数){实现}。

    一边自学,一边总结,有不对的地方请不要吝啬拍砖

  • 相关阅读:
    java 如何判断邮箱是否正确
    Android SDK Manager无法更新的解决
    洛谷P1162
    真 随笔
    初始化结构体
    Linux mkdir -p 后出现permission denied问题
    校赛F
    HDU1022
    UVa156
    HDU1060
  • 原文地址:https://www.cnblogs.com/LLLLoveLLLLife/p/3432757.html
Copyright © 2020-2023  润新知