Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UI update in WPF elements event handlers

There is a problem with UI update in WPF.

I have such code:

    private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
    {
        Label.Visibility = Visibility.Visible;
        TextBox.Text = "Processing...";

        LongTimeMethod(); //some long operation
    }

The problem is that until LongTimeMethod ends (that is event handler ends), Label.Visibility and TextBox.Text will not be changed.

I solved it like this so far:

    private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
    {
        Label.Visibility = Visibility.Visible;
        TextBox.Text = "Processing...";

        Dispatcher.BeginInvoke(new Action(LongTimeMethod), 
            DispatcherPriority.Background);
    }

Is there any other solution without using dispatcher invocation? Calling this.UpdateLayout() doesn't help.

like image 940
brain_pusher Avatar asked Jun 14 '11 15:06

brain_pusher


2 Answers

With Dispatcher.BeginInvoke you are still using the UI thread for LongTimeMethod(). If this is not required (i.e. it is doing some kind of background processing) I would suggest using the TPL to run it on a background thread:

private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
{
    Label.Visibility = Visibility.Visible;
    TextBox.Text = "Processing...";

    Task.Factory.StartNew(() => LongTimeMethod())
        .ContinueWith(t =>
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                TextBox.Text = "Done!";
            });
        });

}

With this method, the long running method is processed on a background thread (so the UI thread will be free to keep rendering and the app won't freeze up) and you can do anything that does alter the UI (such as updating the textbox text) on the UI Dispatcher when the background task completes

like image 167
Steve Greatrex Avatar answered Oct 08 '22 21:10

Steve Greatrex


Visibility and Text are dependency properties which updated by dispatcher. Your solution is absolutely corrent, but my suggestion is to do it asynchronously.

On other hand, you might simulate Application.DoEvents in WPF (see the article).

like image 39
Optillect Team Avatar answered Oct 08 '22 22:10

Optillect Team