Meriç Akgül
Meriç Akgül

Reputation: 173

Want a button to disable for 30 second after click and enable it automatically

I am on a project and this project needs to take randomly 16 bytes from random.org. I can take it from website and write this 16 bytes to a textedit. I also have a refresh button. Everytime this button is clicked, new 16 byte comes and it is written in textedit.

I want to prevent the user to click refresh button sequentially. What I want is to disable refresh button after it is click. However, another thing I want is to enable this button after 30 seconds automatically.

I've tried thread.sleep(30000) in the button click event but it stops whole program for 30 seconds. I want to disable just refresh button for 30 seconds, not the rest of the program.

I am thinking to show to the users kind of stopwatch so that they can see how much time they should wait for next click. For example, after they click refresh button, there appears this 30 seconds stopwatch.

Upvotes: 7

Views: 24480

Answers (7)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34244

Starting from C# 5.0 you can use async/await and Task.Delay to wait for 30 seconds in the middle of the method without blocking the UI thread:

private async void YourButton_Click(object sender, EventArgs e)
{
    UIElement element = (UIElement)sender;

    element.IsEnabled = false;
    await Task.Delay(30000); // 30 seconds
    element.IsEnabled = true;
}

Upvotes: 1

hollen9
hollen9

Reputation: 87

Based on user2737037's answer, here's the annoumous code-behind approach.

In this way, you don't have to declare any member fields, which keep your code clean.

private void btnFoo_Click(object s, RoutedEventArgs e)
{
    var btn = (Button)sender;
    btn.IsEnabled = false; //Disable button.
    var fooTimer = new System.Timers.Timer(5000); //Exceute after 5000 milliseconds
    timer.Elapsed += (fooTimer_s, fooTimer_e) => 
    {
        //It has to be dispatched because of thread crossing if you are using WPF.
        Dispatcher.Invoke(()=>  
        {
            btn.IsEnabled = true; //Bring button back to life by enabling it.
            fooTimer.Dispose();
        });
    };
    fooTimer.Start();

    //Insert your code here :)
}

Upvotes: 2

Ilya
Ilya

Reputation: 231

If we are talking about WPF here, there is a way to achieve the desired behavior with EventTriggers without any code-behind:

 <Style TargetType="Button">

        <Style.Triggers>

            <EventTrigger RoutedEvent="Button.Click">

                <EventTrigger.Actions>

                    <BeginStoryboard>

                        <Storyboard>

                            <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled">

                                <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />

                                <DiscreteBooleanKeyFrame KeyTime="00:00:30" Value="True" />

                            </BooleanAnimationUsingKeyFrames>

                        </Storyboard>

                    </BeginStoryboard>

                </EventTrigger.Actions>

            </EventTrigger>

        </Style.Triggers>

    </Style>

Upvotes: 20

user2737037
user2737037

Reputation: 1157

Try something like this:

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
private void button1_Click(object sender, EventArgs e)  // event handler of your button
{                
    timer.Interval = 30000; // here time in milliseconds
    timer.Tick += timer_Tick;
    timer.Start();
    button1.Enabled = false;

    // place get random code here
}

void timer_Tick(object sender, System.EventArgs e)
{
    button1.Enabled = true;
    timer.Stop();
}

Upvotes: 9

tire0011
tire0011

Reputation: 1058

use a timer there is a snippet to create the timer http://dotnet-snippets.de/snippet/timer-anlegen/111

in the on click in the button disable the button and start the timer. In the Tick enable the button and stop the timer.

Upvotes: 0

Sudhakar Tillapudi
Sudhakar Tillapudi

Reputation: 26209

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
timer1.Interval=1000;//one second
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Start();
int count=30;
private void timer1_Tick(object sender, EventArgs e)
{
   if(count!=0)
   {
   button1.Enabled=false;
   label1.Text =  count.ToString() +" seconds more to Enable Refresh Button";
   count--;
   }
   else
   {
   button1.Enabled=true;
   timer1.Stop();
   }

}

Upvotes: 0

user3108818
user3108818

Reputation: 43

try to use an timer an enable the button after a tick. For more information: http://www.dotnetperls.com/timer

Upvotes: 0

Related Questions