Ben
Ben

Reputation: 4319

How do I update a UI element in WPF before processing the rest of a function?

I want to disable a button as soon as a user clicks it to stop them clicking it again. There are a number of checks that are performed when they click it, and it appears these checks are done before the UI change takes place.

I am trying to do this by using a separate thread for the button, but it still seems to only update after the checks are done.

Here's the code I am using:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Thread t = new Thread(new ThreadStart(
     delegate
     {
         Action action = () => btnStart.IsEnabled = false;
         Dispatcher.BeginInvoke(action);
     }
     ));
     t.Start();          
    // Run the main routine;
    BeginBootstrapping();
}   

How can I disable the button straight away?

Upvotes: 1

Views: 1826

Answers (2)

Clemens
Clemens

Reputation: 128077

You may write an async Click handler that uses a Task to run some background work:

using System.Threading.Tasks;
...

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var button = (Button)sender;
    button.IsEnabled = false;

    await Task.Run(() => DoTheBootstrapping());

    button.IsEnabled = true;
}

Of course if you can make the long running method itself awaitable like

private async Task DoTheBootstrapping()
{
    var httpClient = new HttpClient();
    var content = await httpClient.GetStringAsync("http://stackoverflow.com");
}

you can call it without Task.Run like

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var button = (Button)sender;
    button.IsEnabled = false;

    await DoTheBootstrapping();

    button.IsEnabled = true;
}

Upvotes: 6

Rik The Developer
Rik The Developer

Reputation: 149

private void Button_Click(object sender, RoutedEventArgs e)
{
    btnStart.IsEnabled = false
    Thread t = new Thread(new ThreadStart(
    delegate
    {
        // Run the main routine;
        BeginBootstrapping();
    }));

    t.Start();
}

Like Evk said in his comment, this disables the button right away from the UI thread main thread), then runs the rest of what has to be done on the other thread. Note I'm not using Dispatcher, because Dispatcher is actually the UI thread aswell, and using that will freeze the UI.

Upvotes: 0

Related Questions