none
Button1按第2次時,無法清除textBox1的文字 RRS feed

  • 問題

  • 各位大大們好,小弟跟大家請教一個問題

    private void button1_Click(object sender, EventArgs e)
    {
    textBox1.Text = " ";

    //textBox1.Clear();

    //Clean_TextBox1();

    //textBox1.Text = string.Empty;

    Thread.Sleep(2000); //Delay 1秒

    textBox1.Text = "測試文字~按第2次Button\r\n要先清除間隔2秒後才顯示唷";
    }

    以上程式的目地,是按下button1時,會先清除textBox1的文字,經過2秒後才顯示出測試的文字
    但發生了一個異常現像,當button1按下第2次到第n次時,都無法清除textBox1的文字

    我有在其他論壇問過,有大大告知可用Application.DoEvents();

    如果不使用Application.DoEvents();是否也可以辦到此功能呢?

    請各位大大指導一下,謝謝~



    程式是由VS2013撰寫,可以下方網址取得,謝謝~
    https://drive.google.com/folderview?id=0B9ORcd2U4a0RUDRhNWtXQlFuOVk&usp=sharing

    2016年4月11日 上午 01:19

解答

  • 您可以這樣做:

    textBox1.Text = " ";
    
    textBox1.Refresh();
    
    Thread.Sleep(2000); //Delay 1秒
    
    textBox1.Text = "測試文字~按第2次Button\r\n要先清除間隔2秒後才顯示唷";

    • 已標示為解答 Milton6799 2016年4月13日 上午 02:19
    2016年4月11日 上午 04:11
  • 這用多執行緒處理是比較適合的, 使用多執行緒也有很多種寫法. 上面 Peter 寫的是一種, 以下提供另外一種

     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                textBox1.Text = "這是一開始有的字"; 
            }
    
           
            private void button1_Click(object sender, EventArgs e)
            {
              
                Thread t = new Thread(Do);
                t.IsBackground = true;
                t.Start(); 
    
    
            }
    
            private void Do()
            {
                //跨執行緒存取 UI 必須 要使用 Control.Invoke 方法
                Action clear = new Action(ClearTextBox);
                this.BeginInvoke(clear);
    
                Thread.Sleep(2000);
    
                //跨執行緒存取 UI 必須 要使用 Control.Invoke 方法
                Action setText = new Action(SetTextBox);
                this.BeginInvoke(setText);
    
                
                 
            }
    
            private void ClearTextBox()
            {
                textBox1.Clear(); 
            }
    
            private void SetTextBox()
            {
                textBox1.Text = "測試文字~按第2次Button , 要先清除間隔2秒後才顯示唷";
    
            }
    
        }


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 Milton6799 2016年4月13日 上午 02:21
    2016年4月11日 上午 06:07
    版主

所有回覆

  •         private async void button1_Click(object sender, EventArgs e)
            {
                textBox1.Text = "";
                
                await Task.Run(() => { test(); });
            }
    
            private void test()
            {
                Thread.Sleep(2000);
                textBox1.Text = "測試文字~按第2次Button\r\n要先清除間隔2秒後才顯示唷";
            }
    2016年4月11日 上午 02:33
  • 您可以這樣做:

    textBox1.Text = " ";
    
    textBox1.Refresh();
    
    Thread.Sleep(2000); //Delay 1秒
    
    textBox1.Text = "測試文字~按第2次Button\r\n要先清除間隔2秒後才顯示唷";

    • 已標示為解答 Milton6799 2016年4月13日 上午 02:19
    2016年4月11日 上午 04:11
  • 這用多執行緒處理是比較適合的, 使用多執行緒也有很多種寫法. 上面 Peter 寫的是一種, 以下提供另外一種

     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                textBox1.Text = "這是一開始有的字"; 
            }
    
           
            private void button1_Click(object sender, EventArgs e)
            {
              
                Thread t = new Thread(Do);
                t.IsBackground = true;
                t.Start(); 
    
    
            }
    
            private void Do()
            {
                //跨執行緒存取 UI 必須 要使用 Control.Invoke 方法
                Action clear = new Action(ClearTextBox);
                this.BeginInvoke(clear);
    
                Thread.Sleep(2000);
    
                //跨執行緒存取 UI 必須 要使用 Control.Invoke 方法
                Action setText = new Action(SetTextBox);
                this.BeginInvoke(setText);
    
                
                 
            }
    
            private void ClearTextBox()
            {
                textBox1.Clear(); 
            }
    
            private void SetTextBox()
            {
                textBox1.Text = "測試文字~按第2次Button , 要先清除間隔2秒後才顯示唷";
    
            }
    
        }


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 Milton6799 2016年4月13日 上午 02:21
    2016年4月11日 上午 06:07
    版主
  • 至於設定 TextBox 的 Text 屬性, 還有一種稍微瘋狂的作法, 用繫結的方式.

    像以下這樣:

      public partial class Form1 : Form
        {
            private DisplayData data;
    
            public Form1()
            {
                InitializeComponent();
                data = new DisplayData() { DisplayText = "這是一開始有的字" };
                textBox1.DataBindings.Add("Text", data, "DisplayText"); 
            }
    
    
            private void button1_Click(object sender, EventArgs e)
            {
                
                Thread t = new Thread(Do);
                t.IsBackground = true;
                t.Start();
    
    
            }
    
            private void Do()
            {
                //跨執行緒存取 UI 必須 要使用 Control.Invoke 方法
                Action clear = new Action(ClearTextBox);
                this.BeginInvoke(clear);
    
                Thread.Sleep(2000);
    
                //跨執行緒存取 UI 必須 要使用 Control.Invoke 方法
                Action setText = new Action(SetTextBox);
                this.BeginInvoke(setText);
    
    
    
            }
    
            private void ClearTextBox()
            {
                data.DisplayText = String.Empty;
            }
    
            private void SetTextBox()
            {
                data.DisplayText = "測試文字~按第2次Button , 要先清除間隔2秒後才顯示唷";
    
            }
    
        }
    
        public class DisplayData : INotifyPropertyChanged 
        {
            private string _displayText;
            public string DisplayText
            {
                get { return _displayText; }
                set
                {
                    if (_displayText != value)
                    {
                        _displayText = value;
                        OnPropertyChanged("DisplayText");
                    }
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null )
                {
                    PropertyChanged(this, new PropertyChangedEventArgs (  propertyName));
                }
            }
        }
    }


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2016年4月11日 上午 06:19
    版主
  • 感謝tihs大大的解答,簡單易懂,謝謝~

    2016年4月13日 上午 02:18
  • 感謝Bill大大的指導,但以我初學者的角度,會覺的tihs大大的解答比較方便,如果您願意的話,可以請您說明此寫法的優點嗎?
    2016年4月13日 上午 02:21
  • 感謝Bill大大的指導,但以我初學者的角度,會覺的tihs大大的解答比較方便,如果您願意的話,可以請您說明此寫法的優點嗎?
    2016年4月13日 上午 02:22
  • 感謝Coding Kid Perter Chang大大的指導,但以我初學者的角度,會覺的tihs大大的解答比較方便使用,謝謝~
    2016年4月13日 上午 02:23
  • 基本上 Thread.Sleep 不應該出現在 UI 所在的執行緒, 因為在UI 執行緒中使用 Thread.Sleep 等於在封鎖操作畫面. 也就是當你在 Thread.Sleep 的那段時間, 畫面上的任何東西都是不能被操作的 , 對於正常的商業程式來講, 封鎖使用者操作畫面並不是一個好的使用者經驗設計方式.

    你可以試著回想你在用任何的應用程式時, 當你按了畫面某個東西後, 卻出現 "這個畫面無回應" 的訊息時, 你自己的心情是甚麼 ?

    所以, 這類的東西, 我建議是使用多執行緒處理能比較符合在正式應用的情況, 而且, 如果你以後是要開發桌面應用程式, 執行緒學一學有好沒壞, 會用上的.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。




    2016年4月13日 上午 02:37
    版主
  • 我了解了,謝謝Bill大大的解說~
    2016年4月13日 上午 03:36
  • 你好~

    以下提供另外一種 用 Task 的方式 

    http://note.jhpeng.com/CSharp_Task/

    2016年4月17日 下午 10:24