Robbo905
Robbo905

Reputation: 45

TextBlock Will Not Update

I have a text block called "findListText". Here, I am updating the text in it:

private void InstantSearch(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        HitEnter = true;
    }
    findListText.Text = "Processing request. Please wait...";
    Find(bool.Parse("False" as string));
}

However, the next set of code is a search function that can take up to 10 seconds, and at the end of it, it changes the text in findListText again.

private void Find(bool? bForward = true)
{
    {
        //Lots and lots of code
    }
    findListText.Text = "Search completed."
}

The problem is, the textblock never seems to update to "Processing request. Please wait...". The textblock is in it's original state and 10 seconds later updates to "Search completed.", seemingly skipping out the middle man.

I'm using C# - WPF. What am I doing wrong here?

Upvotes: 3

Views: 7684

Answers (5)

Robbo905
Robbo905

Reputation: 45

I came back to this just now, and had another browse across the internet for similar problems. For something as simple as pushing a single message before a long running process occurs, I'm surprised no-one suggested "Application.DoEvents();". Yes, I know it has it's flaws, and my UI will still hang, but this suits me perfectly for my situation, at least.

Upvotes: 0

Terry
Terry

Reputation: 5282

Doesn't matter what technology I think.

The code is running on the same thread, meaning the the UI won't be updated untill all the code on that thread is completed. You should address a different thread to update that textblock.

In that case, you will have 2 thread:

  • The origininal thread, executing the "lots and lots of code"
  • The second (extra) created thread, which will handle updating the textblock's text while the other thread is executing the other code.

I've created a little something that should resolve your problem, it's based on this Stack Overflow page

Upvotes: 4

Myrtle
Myrtle

Reputation: 5851

You should look into the UI threading concept of WPF. Invoke the Dispatcher to modify the textbox. Also the search should run with ThreadPool.QueueWorkerItem.

// Start worker thread
ThreadPool.QueueUserWorkItem(state =>
{
    // Long running logic here
   findListText.Dispatcher.BeginInvoke(() => findListText.Text = "Processing request. Please wait...");
   Find(bool.Parse("False" as string)); 


    // Tip: Run change on GUI thread from the worker using the dispatcher
    findListText.Dispatcher.BeginInvoke(() => findListText.Text = "Search completed.");
});

Upvotes: 1

steveg89
steveg89

Reputation: 1827

Here is how to run your find method in its own thread.

private void InstantSearch(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        HitEnter = true;
    }
    findListText.Text = "Processing request. Please wait...";
    BackgroundWorker tempWorker = new BackgroundWorker();
    tempWorker.DoWork += delegate
    {
       Find(bool.Parse("False" as string));
    };
    tempWorker.RunWorkerAsync();
}

If you try that, you'll get an error because you access your UI thread from the background thread. So you'll need to update your find method as well.

private void Find(bool? bForward = true)
{
   {
       //Lots and lots of code
   }
   Dispatcher.BeginInvoke((Action) delegate {
      findListText.Text = "Search completed."
   });
}

Upvotes: 1

Andre Calil
Andre Calil

Reputation: 7692

Since this is WPF, try the following: after changing the text to "Processgin", call:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { this.UpdateLayout(); }));

This will tell the thread to update the UI as soon as possible.

Upvotes: 2

Related Questions