0

I'm setting my first steps in C#, and I'm making a small application, based on a System.Windows.Forms.Form, on which I've placed a simple button. When this button is clicked, I do something which takes quite some time and I would like to modify the Text property of that button while the operation is taking place.

This is what I have done (don't laugh :-) ):

        private void btn_STUFF_Click(object sender, EventArgs e)
        {
            string temp_Title = btn_STUFF.Text;
            btn_STUFF.Text = "Busy";
            this.Refresh();
            this.Update();
            this.Show();
            string temp = Do_Something_Which_Takes_Quite_Some_Time();
            txt_output.Text = temp;
            btn_STUFF.Text = temp_Title;
        }

Despite the Refresh(), the Update() and the Show() I don't see my button mentioning the word "busy".

How can I force my application to refresh the attributes of the components on the form (as easy as possible, please) ?

Thanks in advance

Dominique
  • 16,450
  • 15
  • 56
  • 112

2 Answers2

0

Try this

private async void button3_Click(object sender, EventArgs e)
        {
            string currentText = button3.Text;

            button3.Invoke(new Action(() =>
            button3.Text = "Busy"
            ));

            //long running task
            await Task.Run(() => Task.Delay(5000));

            button3.Invoke(new Action(() =>
                button3.Text = currentText
                ));
        }
Amit Verma
  • 2,450
  • 2
  • 8
  • 21
0

Use BackgroundWorker for WinForms (inside System.ComponentModel), it is simple and easy to use,

        private BackgroundWorker myWorker;

        public Form1()
        {
            InitializeComponent();
            myWorker = new BackgroundWorker();
            myWorker.DoWork += MyWorker_DoWork;
            myWorker.RunWorkerCompleted += MyWorker_RunWorkerCompleted;
        }

        private void MyWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnTest.Text = "Test";
            btnTest.Enabled = true;
        }

        private void MyWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            ChangeControlPropThreadSafe(btnTest, () => btnTest.Text = "This button is busy!");
            ChangeControlPropThreadSafe(btnTest, () => btnTest.Enabled = false);
            Thread.Sleep(5000);
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            myWorker.RunWorkerAsync();
        }
        private void ChangeControlPropThreadSafe(Control control, MethodInvoker action)
        {

            if (control.InvokeRequired)
            {
                control.Invoke(action);
            }
            else
            {
                action();
            }
        }

Result:

enter image description here

enter image description here

Mansur Kurtov
  • 726
  • 1
  • 4
  • 12