2

I´d like to change the text of a TextBlock during a Button_Click in WPF. I tried this but it did not work:

private void Button_Click(object sender, RoutedEventArgs e)
{
    myTextBlock.Text = "Status: Not ready";

    //Do Something

    myTextBlock.Text = "Status: Ready";

}
Milo
  • 3,365
  • 9
  • 30
  • 44
Victor .S
  • 37
  • 8
  • **on button click or during button click**? – Prasad Telkikar Feb 27 '18 at 14:23
  • Possible duplicate of [C# - Overwrite / Update text in TextBlock](https://stackoverflow.com/questions/45721074/c-sharp-overwrite-update-text-in-textblock) – DeveloperExceptionError Feb 27 '18 at 14:23
  • When you say it doesn't work, do you mean it never changes, or one of those states is never hit? – Fabulous Feb 27 '18 at 14:27
  • What do you mean by it didn't work? What was the expected outcome and what was the given output? –  Feb 27 '18 at 14:27
  • 2
    I am guessing your problem is that you do not see the "Status: Not Ready" text - because the UI update is on the same thread as the click event - so only done after the click event exits. See this [question](https://stackoverflow.com/questions/6843327/refresh-wpf-control-by-code) for an Extension method to add a Refresh method for WPF controls. After setting the text call myTextBlock.Refresh(); - Note using "DispatcherPriority.Input" rather then "DispatcherPriority.Render" may work better. – PaulF Feb 27 '18 at 14:28
  • It updates after the Button_Click but I changed it back to "Status: Ready" so "it does not change" – Victor .S Feb 27 '18 at 14:30
  • Do you enter Button_Click method ? You can set a debugger and check if it actually fired. Also try Dispatching this code on a main thread – Vladimir Feb 27 '18 at 14:30
  • There is a blog that contains the code in the SO question I gave you a link to here : http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx - the comment about using "DispatcherPriority.Input" is a few comments down after the main article. – PaulF Feb 27 '18 at 14:36

3 Answers3

3

Button_Click is called out of the UI thread. This means executed code will block updating your UI. A simple solution is to use async and await and a new thread to run your blocking action. This allows the UI thread to update the UI during the blocking action.

private async void Button_Click(object sender, RoutedEventArgs e)
{
    myTextBlock.Text = "Status: Not ready";

    await Task.Run(() =>
    {
        //Your code here
    }).ConfigureAwait(true);

    myTextBlock.Text = "Status: Ready";
}

Note that you need to add ConfigureAwait(true) to use the UI thread again to update the text the second time.

Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
0

You need to replace the comment //Do Something with some code that actually does something on another thread. If you don't, you will never get the chance to see the "Status: Not ready" message as the Text property will be set to "Status: Ready" almost immediately after you have clicked the Button.

Try this:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    myTextBlock.Text = "Status: Not ready";

    await Task.Delay(3000); //wait asynchronously for 3 seconds..

    myTextBlock.Text = "Status: Ready";

}

After you have confirmed that this works as expected you probably want to start a task that does something meaningful as suggested by @Fruchtzwerg. ConfigureAwait(true) is superfluous here though:

await Task.Run(() =>
{
    //Do something
});
mm8
  • 163,881
  • 10
  • 57
  • 88
0

To avoid writing all the processing in the thread i do it :

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            
             myTextBlock.Text = "Status: Not ready";
             await Task.Run(() =>
             {
                 Thread.Sleep(1000);
             }).ConfigureAwait(true);

             //Do your processing
             Treatment();

             myTextBlock.Text = "Status: Ready";
        }
Quentin Couderc
  • 86
  • 2
  • 12