Search code examples
c#xamlwinui-3

How to disable a button after click for only 3 seconds in a WinUI 3 Application?


I have a button that I want to disable for 3 seconds so that it's not abused. I wanted to add a Timer(3000); inside the Click event however the example code I found is using outdated method and is not working. I tried another code (which can be found below) however this throws System.Runtime.InteropServices.COMException: 'The application called an interface that was marshalled for a different thread. (0x8001010E (RPC_E_WRONG_THREAD))' error.

private void CodeButton_Click(object sender, RoutedEventArgs e)
{
    CodeButton.IsEnabled = false;
    var timer = new Timer(3000);
    timer.Elapsed += (timer_s, timer_e) =>
    {
            CodeButton.IsEnabled = true;
            timer.Dispose();

    };
    timer.Start();
    Launcher.LaunchUriAsync(new Uri("https://www.hoppie.nl/acars/system/register.html"));
}

Solution

  • You need to use the main thread (the thread that instantiated UI components) to update UI. You get that error because the timer will work with another thread, not the main thread.

    You can do it this way:

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            // You can update the UI because
            // the Click event will use the main thread.
            this.Button.IsEnabled = false;
    
            List<Task> tasks = new();
            // The main thread will be released here until
            // LaunchUriAsync returns.
            tasks.Add(Launcher.LaunchUriAsync(new Uri("https://www.hoppie.nl/acars/system/register.html")));
            tasks.Add(Task.Delay(3000));
            await Task.WhenAll(tasks);
            // The main thread will be back here.
        }
        finally
        {
            // This will enable the button even if you face exceptions.
            this.Button.IsEnabled = true;
        }
    }